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

Linking to DLL in C++ - same code works with Visual Studio, but not with MinGW

本文关键字:适用于 Studio Visual MinGW 不适用 代码 C++ 中的 DLL 链接      更新时间:2023-10-16

我正试图在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中的某个位置,第二个调用使程序崩溃。有人能理解这一点吗?

不幸的是,各种编译器在如何实现这些所谓的标准调用约定方面存在许多细微的差异。

我在让Borland C++编译器调用Microsoft DLL时遇到了类似的问题,尽管使用标准调用约定将接口定义为外部"C"。

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

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

编辑:此页面有一个stdcall的低级描述,您可以使用它与MinGW编译器正在生成的汇编程序进行campare。

不同的编译器执行不同的名称篡改。您需要使用兼容的编译器编译所有C++项目,使其正确链接。

相关文章: