1. 程式人生 > >VS2015下解決:無法解析的外部符號 __imp___vsnprintf 及__iob_func

VS2015下解決:無法解析的外部符號 __imp___vsnprintf 及__iob_func

1、解決:無法解析的外部符號 __imp___vsnprintf

在 vs2015 工程選項,連結器附加依賴項裡面新增 legacy_stdio_definitions.lib 即可。

出現這個問題的原因是 vs2015 預設編譯時將許多標準庫採用內聯方式處理,因而沒有可以連結的標準庫檔案,所以要專門新增標準庫檔案來連結標準庫中的函式。

2、解決:無法解析的外部符號__iob_func

在使用 VS2015 下使用 libjpeg-turbo 靜態庫,編譯時報錯了:

error LNK2019: 無法解析的外部符號 __iob_func,該符號在函式 output_message 中被引用

根據關鍵字在網上找到一些文章描述了類似的錯誤,大都是找不到外部符號 __iob ,原因是VS2010上使用了 VC6 編譯的 DLL 。雖然與我的情況不同,但是原理是一樣的,我遇到的這個問題的原因是 VS2015 下使用VS2010編譯的靜態庫,因為我用的libjpeg-turbo靜態庫是從官網下載編譯好的版本(應該是vs2010這樣的版本編譯的)。

其實 __iob_func 和 __iob 都是用來定義 stdin,stdout,stderr,只是不同的VC版本實現方式不同。

下面是VS2015的標頭檔案corecrt_wstdio.h中對stdin,stdout,stderr定義

ACRTIMP_ALT FILE* __cdecl __acrt_iob_func(unsigned);

#define stdin  (__acrt_iob_func(0))
#define stdout (__acrt_iob_func(1))
#define stderr (__acrt_iob_func(2))

原來在 VS2015 中 __iob_func 改成了 __acrt_iob_func ,所以我參照《【LNK2019】 無法解析的外部符號 __iob》這篇文章的方法在自己的程式碼中增加了一個名為 __iob_func 轉換函式:

/*
 * 當libjpeg-turbo為vs2010編譯時,vs2015下靜態連結libjpeg-turbo會連結出錯:找不到__iob_func,
 * 增加__iob_func到__acrt_iob_func的轉換函式解決此問題,
 * 當libjpeg-turbo用vs2015編譯時,不需要此補丁檔案
 */
#if _MSC_VER>=1900
#include "stdio.h" 
_ACRTIMP_ALT FILE* __cdecl __acrt_iob_func(unsigned); 
#ifdef __cplusplus 
extern "C" 
#endif 
FILE* __cdecl __iob_func(unsigned i) { 
    return __acrt_iob_func(i); 
}
#endif /* _MSC_VER>=1900 */

再次編譯,錯誤消失。