为什么 LoadLibrary 失败而 LoadLibraryA 成功加载 DLL?

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

我正在尝试将 DLL 加载到 C++ 中,但收到错误代码 126,我认为这意味着无法找到 DLL。经过一番摸索后,我将 LoadLibrary 更改为 LoadLibraryA 并且突然间它起作用了。但是,我完全不知道为什么。我意识到我没有为这段代码提供可运行的 dll,但如果有人可以解释为什么会发生这种情况,那将是非常好的?并且可能是一个如何让 LoadLibary 工作的例子。

破解版

#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;
}

编译并输出

Error loading dll: 126/nHit any key to continue

控制台

工作版本

#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;
}

编译输出

version is: 1.3.4

您的 LoadLibrary((LPCWSTR)"libsbnw.dll") 调用的问题是您的构建环境将其转换为 LoadLibraryW 调用,但是您尝试传递宽字符字符串的方式是错误的。

正如你所拥有的,你只是将一个 const char* 指针转换为一个 const wchar_t* 指针,这是行不通的(例如,它将解释初始的 "li" 字符作为单个 16 位字符)。

您需要做的是使用 L 前缀将字符串文字指定为 宽字符 常量:

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

或者,或者,使用 TEXT() 宏(当使用 UNICODE 构建环境时,这将归结为相同的):

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

随时要求进一步解释and/or澄清。

通常编译器会在您犯错时尝试指出。但在这种情况下,您已通过向字符串添加显式强制转换来告诉它不要这样做。

HINSTANCE hLib = LoadLibrary((LPCWSTR)"libsbnw.dll");
                           //^^^^^^^^^

我假设您构建的应用程序启用了 Unicode,它定义了一个将 LoadLibrary 转换为 LoadLibraryW 的宏。参数必须是 宽字符 字符串。

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

当您不确定应用程序是否会使用 Unicode 编译时,可以使用另一个宏 TEXT() 或更短的形式 _T()。不推荐用于现代代码,因为多年来需要打开或关闭 Unicode 一直不是问题,只需始终使用 Unicode。

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