問題出現
編譯平台:VS2013 Windows
出現地方:在使用LoadLibrary( )函數動態鏈接DLL文件時出現的一個問題
Eg. 在使用 UNICODE字符的工程中,
HINSTANCE hIcmp = LoadLibrary( "ICMP.DLL" );
報錯:error C2664: “HMODULE LoadLibraryW(LPCWSTR)”:
無法將參數 1 從“const char [9]”轉換為“LPCWSTR”
分析原因
當前工程只支持Unicode字符,不支持多字節,此時如果代碼中出現多字節字符串, 就會報錯。LoadLibrary 函數有兩個版本,一個LoadLibraryW 針對Unicode版的,一個是LoadLibraryA 針對Multi-Byte(多字節)版的,它們通過不同的宏定義區分開,根據定義的宏會使用不同的函數版本。當使用UNICODE字符,就等於預設了_UNICODE、UNICODE宏,所以編譯時就會使用LoadLibraryW。
注:Unicode字符和寬字符可以看作等同
解決方法
1,網上貼了很多,什么修改項目屬性->配置屬性-->常規--->字符集---->使用多字節符字符集。這種方法對於一些小工程可能適用,但是對於一些大的項目,特別是多人協作完成的項目來說,改變了字符集,其他工程也會報錯。 ——不建議采取
2,在需要變為寬字節的字符串前邊,加上 L 或者 _T( ) ;
Eg. HINSTANCE hIcmp = LoadLibrary( L"ICMP.DLL" );
或者 HINSTANCE hIcmp = LoadLibrary( _T( "ICMP.DLL" ) );
注: _T( )還需要加上頭文件 < tchar.h >
3, 如果想在使用UNICODE字符的工程中使用多字節字符,也可以通過宏自定義設置
理解 L 和 _T( )
查看tchar.h頭文件的定義,可以發現_TEXT()和_T()功能是一樣的,而且都是一個預定義的宏。
1 #define _T(x) __T(x) 2 #define _TEXT(x) __T(x)
我們再看看__T(x)的定義,發現它有兩個:
1 #ifdef _UNICODE 2 // ... 省略其它代碼 3 #define __T(x) L ## x 4 // ... 省略其它代碼 5 #else /* ndef _UNICODE */ 6 // ... 省略其它代碼 7 #define __T(x) x 8 // ... 省略其它代碼 9 #endif /* _UNICODE */
可以看出,_T( ) 是一個適配的宏,當工程采用Unicode字符時 _T()就是 L,會將多字節的字符串轉化為Unicode字符,而工程采用多字節字符集時,就會當作一般的字符串處理,不做轉換。
參考鏈接:https://www.cnblogs.com/codingmengmeng/p/6707909.html