将带有 LoadLibrary 的 C DLL 加载到 C++ 应用程序中,调用约定错误

Loading a C DLL with LoadLibrary into a C++ Application, Calling Convention Errors

提问人:John Alway 提问时间:12/8/2020 更新时间:12/8/2020 访问量:564

问:

我正在将Visual Studio 2019与C++一起使用。

我正在尝试将用 C 代码(不是我)编写的 32 位 DLL 加载到我的 C++ 应用程序中。dll 叫做 SDL_mixer.dll(它的早期版本,SDL_mixer-1.2.12,这是必需的)。我必须通过 LoadLibrary() 加载它,因为我没有导入库。我键入了要导入的函数,并使用 GetProcAddress() 访问其中一个函数。它访问它,但在调用函数时引发错误。它给出了问题原因的猜测。

它指出:

“ESP 的值未在函数调用中正确保存。这 通常是调用一个调用一个声明的函数的结果 使用不同调用声明的函数指针的约定 约定”

我不确定我犯了什么错误。我有时使用 LoadLibrary 方法从 C++ 应用程序调用 C DLL 并成功。

这是我拥有的代码:

typedef int (WINAPI* Mix_OpenAudioA)(int frequency, Uint16 format, int channel, int chunksize);


int main()
{
    const HINSTANCE hLibrary = LoadLibrary(L"SDL_mixer.dll");

    if (hLibrary == NULL) {
        cout << "Unable to open SDL_mixer.dll\n";
        return 0;
    }

    Mix_OpenAudioA mx_OpnAudio = (Mix_OpenAudioA)GetProcAddress(hLibrary, "Mix_OpenAudio");

     // Calling this function is where the error occurs
    if (mx_OpnAudio(44100, AUDIO_S16, 2, 512) < 0) {
        cout << "Audio Initializer Error\n";
        return 0;
    }
}

感谢您的帮助! ...John

C++ DLL 调用约定 加载库 getprocaddress

评论

0赞 Mike Vine 12/8/2020
您是否从 64 位程序调用 32 位 dll。
0赞 lsalamon 12/8/2020
在此处验证调用约定
2赞 Hans Passant 12/8/2020
我在 SDL 源代码中没有看到您应该使用 WINAPI(又名)的提示。它也不是那种会偏爱它的图书馆。因此,请将其删除并重试。__stdcall
0赞 John Alway 12/8/2020
@Mike Vine -- 不,它是一个 32 位应用程序。
0赞 John Alway 12/8/2020
@Hans Passant -- 谢谢!就是这样。关于这些调用约定,我有很多东西要学。

答: 暂无答案