Search code examples
c++dlldllexport

Exporting functions from DLLs, LoadLibrary() needs the string cast with TEXT to compile without error


I'm learning to write and use DLLs and this is my first attempt at exporting a function from my dll. It works, but this line is what gave me trouble and what I've been able to find regarding the TEXT cast for UNICODE and ANSI I think I need some guidance. As far as I can find this question has not been asked elsewhere on the site so I apologize if anyone finds what I couldn't.

HINSTANCE hInstLibrary = LoadLibrary("MyDLL.dll"); 

My initial usage, from a short tutorial on explicit linking gives E0167 and C2664 errors regarding LPCWSTR type

HINSTANCE hInstLibrary = LoadLibrary(TEXT("MyDLL.dll"));

Casting the string to TEXT solves the problem, though I'm not sure why and would like to know

HINSTANCE hInstLibrary = LoadLibraryA("MyDLL.dll");

The line I decided to use in the working example. LoadLibraryA() expands LoadLibrary to accept ANSI rather than Wide, which may be the root of my misunderstanding. Why is this necessary when most examples I find show LoadLibrary("NameOfDLL.dll")?

Why does the string not satisfy the standard LoadLibrary() call?


Solution

  • LoadLibrary() is a preprocessor macro. It maps to either LoadLibraryW() or LoadLibraryA() depending on whether UNICODE is defined or not, respectively. LoadLibraryW() takes a const wchar_t* string as input, while LoadLibraryA() takes a const char * string instead.

    The string literal "MyDLL.dll" is a const char[10], which decays into a const char *. If UNICODE is defined, LoadLibrary("MyDLL.dll") will fail to compile, as you cannot pass a const char * where a const wchar_t * is expected.

    TEXT() is also a preprocessor macro. If UNICODE is defined, it appends an L prefix to the specified literal making the literal use wchar_t, otherwise no prefix is added and the literal uses char instead.

    Thus, if UNICODE is defined, then LoadLibrary(TEXT("MyDLL.dll")) is compiled as LoadLibraryW(L"MyDLL.dll"), otherwise it is compiled as LoadLibraryA("MyDLL.dll") instead.

    A majority of Win32 APIs that deal with textual data have similar A and W versions, and corresponding UNICODE-aware preprocessor macros. So, when using character/string literals with these APIs, you should always use the TEXT() macro. Otherwise, just use the A and W APIs directly as needed, depending on the type of textual data you are working with.