c++ - 链接到 C++ 中的 DLL - 相同的代码适用于 Visual Studio,但不适用于 MinGW

标签 c++ visual-studio dll mingw

我正在尝试在 MinGW 项目中使用第三方 dll;该 dll 带有一个 .lib 和一个 .h 文件。这是我正在尝试做的事情的一个简单示例:

#include <iostream>


using namespace std;


extern "C" {
    long __declspec(dllimport) _stdcall C843_Connect(long iBoardNumber);
}


int main(int argc, char* argv[]) {
    cout << "Attempting to connect..." << endl;
    long ID = C843_Connect(1);
    if (ID<0) {
        cout << "Connection failed!" << endl;
        return 1;
    }
    cout << "Connection succesful! ID: " << ID << endl;
    return 0;
}

函数声明直接取自头文件。代码使用 MinGW 正常编译,但每次调用 C843_Connect(long) 时生成的程序都会崩溃。然而,完全相同的代码在使用 MS Visual Studio 2010 编译时运行良好。(我猜 dll 是用 Visual Studio 构建的,因为它附带了一些 VS 示例项目。)任何想法可能会出错以及我如何能让 dll 与 MinGW 一起工作?

编辑:我运行了程序和调试器,崩溃是由于调用错误地址造成的。这是程序崩溃前的最后四行反汇编代码:

Address   Hex dump          Command
00401419  |.  E8 B2300300   CALL 004344D0
0040141E  |.  C70424 010000 MOV DWORD PTR SS:[ESP],1
00401425  |.  A1 68724700   MOV EAX,DWORD PTR DS:[477268]
0040142A  |.  FFD0          CALL EAX

第一次调用转到 msvcrt.dll 中的某处,第二次调用使程序崩溃。任何人都可以理解这一点吗?

最佳答案

不幸的是有很多subtle differences了解各种编译器如何实现这些所谓的标准调用约定。

我在让 Borland C++ 编译器调用 Microsoft DLL 时遇到了类似的问题,即使该接口(interface)使用标准调用约定定义为 extern "c"。

在我的例子中,代码实际上运行了入口点,但它在返回时失败了,因为两个编译器无法就如何处理位于堆栈的返回地址达成一致。

例如,当使用 Microsoft c/c++ 编译器重新编译完全相同的代码时,我的问题就消失了。

编辑这个page具有 stdcall 的低级描述,您可以使用它来与 MinGW 编译器生成的汇编程序进行比较。

关于c++ - 链接到 C++ 中的 DLL - 相同的代码适用于 Visual Studio,但不适用于 MinGW,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9253606/

相关文章:

C++ 继承和成员函数指针

c++ - 可以在多态 lambda 中使用结构化绑定(bind)语法吗

c# - 显示重新抛出的异常的堆栈跟踪,而不是从抛出点开始的堆栈跟踪

python - Django 测试客户端 POST 不发送数据

dll - 类未注册错误

c++ - MinGW隐藏dll中的方法名称

c++ - MSVC 2017 在共享库中创建模板函数的拷贝

c++ - 将来自套接字的 read() 的输出存储在 char 变量中

mysql - 带有 MYSQL 的 Entity Framework 6(Visual Studio 开发 > Visual Studio 集成)

c++ - 如何在 C++ 中实现以逗号分隔的初始化,例如 Eigen 中的初始化?