【问题标题】:DLL calling conventions & access violationDLL 调用约定和访问冲突
【发布时间】:2016-11-16 10:14:11
【问题描述】:

在这个伟大的平台上阅读和学习多年后,现在我的第一篇文章。

我的问题:

在 C++ 中,我尝试创建一个动态链接库(32 位),用作 AQMP 通信客户端(基于 SimpleAmqpClient)。 dll 文件将在第三方应用程序(32 位)中使用。

在我在自定义可执行文件中调用 dll 的测试期间,一切正常。但是当我尝试在第三方应用程序中使用 dll 时,我收到了访问冲突错误 (0x00000000)。我发现问题可能出在函数调用约定上。

通过下面显示的几行代码,可以重现该错误。如果我删除 mytest.dll 中的 __stdcall 表达式,它就会消失。通常我希望代码能够工作,因为它在 custom_test.exe 和 mytest.dll 中使用相同的调用约定。 (旁注:第三方应用程序需要 __stdcall 函数,这就是我依赖它的原因)

我想了解这种行为。提前致谢!

我的设置:

  • 操作系统:Windows 7
  • 32 位编译器:gcc 5.3 (Cygwin)

我的代码 (custom_test.exe):

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


int main(void) {

    HINSTANCE hInstance;    
    hInstance=LoadLibrary("mytest.dll");
    FARPROC lpfnGetProcessID = GetProcAddress(HMODULE(hInstance), "test");

    // Function prototype
    typedef void (__stdcall *myFunction)(void);
    myFunction test;
    test = myFunction(lpfnGetProcessID);

    // Call Function
    test();

    FreeLibrary(hInstance);
}

我的代码(mytest.dll):

extern "C" __declspec(dllexport) void __stdcall test(void) {

    printf("Inside Function \n");
}

我通过编译代码

  • dll:g++ mytest.cpp -o mytest.dll -shared -std=gnu++11
  • exe:g++ custom_test.cpp -o custom_test.exe -std=gnu++11

【问题讨论】:

    标签: c++ dll stdcall


    【解决方案1】:

    __stdcall 约定让被调用函数负责在返回时清理堆栈,而 __cdecl 则让调用者负责。

    我们看不到第三方 DLL 中的实际声明,但我最初的假设是 DLL 需要参数,并且要么错误地使用了它认为是堆栈参数的东西,要么正在清理基于堆栈的参数这是对堆栈参数的假设,并且通常会弄乱您的堆栈。

    编辑 不过,在这种情况下,我看到在 32 位编译时,测试函数以“test@0”的名称导出。如果您将 GetProcAddress 更改为使用此修饰名称,它将起作用。

    【讨论】:

    • 感谢您的回复!在我的第一篇文章中,我只想展示我的任务的全局。只需使用给定的代码即可重现该错误,无需任何进一步的依赖项(第三方库或应用程序)。
    • 更新了答案 - 请参阅编辑
    【解决方案2】:

    好的,几个小时后我又可以看清楚了!感谢 IanM_Matrix1 的建议,所谓的名称装饰确实是重点。

    经过研究,我现在可以分享一些我发现的有用资源: 重要的是要知道一些编译器会为函数名称添加不同的修饰,请参见此处: http://wyw.dcweb.cn/stdcall.htm

    考虑到这一点,您可以阅读此页面,了解一般的 Win32 调用约定: http://www.unixwiz.net/techtips/win32-callconv.html

    使用 gcc 时,也可以通过标志 -Wl,--kill-at 禁用装饰。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-03-19
      • 1970-01-01
      • 1970-01-01
      • 2010-11-19
      • 1970-01-01
      • 2013-03-31
      • 2012-09-12
      相关资源
      最近更新 更多