Search code examples
c++winapidllloadlibrary

Why does LoadLibrary fail whilst LoadLibraryA succeeds in loading a DLL?


I'm trying to load a DLL into C++ but was getting error code 126, which I think means the DLL couldn't be found. After some poking around I changed LoadLibrary to LoadLibraryA and suddendly it worked. However, I am at a complete loss as to why. I realise that I haven't provided the dll for this code to be runable but would be greatful if somebody could provide an explaination as to why this is happening? And prehaps an example of how to get LoadLibary working.

Broken version

#include <stdio.h>
#include <windows.h>

typedef char* (*gf_getCurrentLibraryVersion) ();

int main() {

    gf_getCurrentLibraryVersion getVersion;

    HINSTANCE hLib = LoadLibrary((LPCWSTR)"libsbnw.dll");
    if (hLib) {
        getVersion = (gf_getCurrentLibraryVersion)GetProcAddress(hLib, "gf_getCurrentLibraryVersion");
        printf("Version = %s\n", getVersion());
    }
    else {
        printf("Error loading dll: %d/n", GetLastError());
    }
    printf("Hit any key to continue\n");
    getchar();

    return 0;
}

Compiles and outputs

Error loading dll: 126/nHit any key to continue

to console

Working version

#include <stdio.h>
#include <windows.h>

typedef char* (*gf_getCurrentLibraryVersion) ();

int main() {

    gf_getCurrentLibraryVersion getVersion;

    HINSTANCE hLib = LoadLibraryA("libsbnw.dll");
    if (hLib) {
        getVersion = (gf_getCurrentLibraryVersion)GetProcAddress(hLib, "gf_getCurrentLibraryVersion");
        printf("Version = %s\n", getVersion());
    }
    else {
        printf("Error loading dll: %d/n", GetLastError());
    }
    printf("Hit any key to continue\n");
    getchar();

    return 0;
}

Compiles and outputs

version is: 1.3.4

Solution

  • The problem with your LoadLibrary((LPCWSTR)"libsbnw.dll") call is that your build environment converts that to a LoadLibraryW call, but the way you are trying to pass a wide-character string is wrong.

    As you have it, you are simply casting a const char* pointer to a const wchar_t* pointer, which won't work (for example, it will interpret the initial "li" characters as a single 16-bit character).

    What you need to do is specify the string literal as a wide character constant, using the L prefix:

     HINSTANCE hLib = LoadLibrary(L"libsbnw.dll");
    

    Or, alternatively, using the TEXT() macro (which will boil down to the same, when using the UNICODE build environment):

     HINSTANCE hLib = LoadLibrary(TEXT("libsbnw.dll"));
    

    Feel free to ask for further explanation and/or clarification.