loadlibrary释疑

  • Post author:
  • Post category:其他











在利用


loadlibrary


显示装载某动态库的时候例如:





HINSTANCE hDll = LoadLibrary(“./abc.dll”);





结果编译器报错说不能将


char[]


转换为


LPCWSTR,
















查阅msdn函数原型为
















HMODULE WINAPI LoadLibrary(

__in          LPCTSTR


lpFileName



);



将代码改为:





HINSTANCE hDll = LoadLibrary(LPCWSTR(“./abc.dll”));





编译通过但是会发现hdll为空,装载不成功。


但如果改为












HINSTANCE hDll = LoadLibrary(TEXT(“./abc.dll”));



结果


hDll


不为零,加载成功。为什么?










这是因为使用了UNICODE字符集的原因,

LoadLibrary


实际是使用


LoadLibraryW


而非


LoadLibraryA



而相应的,该函数所需要的参数应该为宽字符串(即



UNICODE



字符串)而非窄字符串


(


多字节字符串)。

C/C++


代码中,直接使用


“”(


双引号


)


包含方式定义的字符串为窄字节串,使用


”(


单引号


)


包含方式定义的字符为窄字符


(


单字节字符或多字节字符


).


而在上述字符串方式中附加


L


前缀则可以变窄字符


(





)


为宽字符


(





).


比如


:

“a”


窄字符串



‘a’


窄字符



L”a”


宽字符串



L’a’


宽字符

windows


头文件中提供了


TEXT


宏可以视



UNICODE



宏是否定义来自动切换由其定义的字符串,其定义大体如下


:

#ifdef


UNICODE



#define TEXT(s) L##s

#else

#define TEXT(s) s

#endif

##


为宏定义中使用的拼接符












对于


LoadLibrary()


这种带有字符串参数的


Windows API


函数,其影射原型也依赖于



UNICODE



宏,大体如下


:

WINBASEAPI

__out

HMODULE

WINAPI

LoadLibraryA(

__in LPCSTR lpLibFileName

);

WINBASEAPI

__out

HMODULE

WINAPI

LoadLibraryW(

__in LPCWSTR lpLibFileName

);

#ifdef


UNICODE



#define LoadLibrary  LoadLibraryW

#else

#define LoadLibrary  LoadLibraryA

#endif // !


UNICODE

LoadLibraryA


使用


LPCSTR


作为参数类型,它即为窄字符串


(A


代表


ANSI)

LoadLibraryW


使用


LPCWSTR


作为参数类型,它即为宽字符串


(W


代表


WIDEN)



因此,不按上述方式使用


API


,一则导致编译错误,如下


:

1 .HINSTANCE hDll = LoadLibrary(“./abc.dll”);



结果编译器报错说不能将


char[]


转换为


LPCWSTR,


结果我就将代码改为:



HINSTANCE hDll = LoadLibrary(LPCWSTR(“./abc.dll”));



则导致运行错误,原因是


LPCWSTR(“”)


是强制类型转换,而非宏替换。


结果


hDll


显示为零,表明加载不成功。



下面的方式才是正确的:



HINSTANCE hDll = LoadLibrary(TEXT(“./abc.dll”));



另外,根据上述分析:下面的


2


种方式同样也是正确的


:

HINSTANCE hDll = LoadLibraryA(“./abc.dll”);

HINSTANCE hDll = LoadLibraryW(L”./abc.dll”);










注: TEXT相当于MFC中的_T()

















vs6下面很多地方使用字符串时直接双引号就行,vs08下面很多地反使用的就是Unicode所以想需要加上_T()