链接到C ++中的DLL-相同的代码适用于Visual Studio,但不适用于MinGW [英] Linking to DLL in C++ - same code works with Visual Studio, but not with MinGW

查看:123
本文介绍了链接到C ++中的DLL-相同的代码适用于Visual Studio,但不适用于MinGW的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to use a third-party dll in a MinGW project; the dll came with a .lib and a .h file. Here is a boiled down example of what I'm trying to do:

#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配合使用?

The function declaration is taken straight from the header file. The code compiles normally with MinGW, but the resulting program crashes every time when calling C843_Connect(long). However, the exact same code runs nicely when compiled with MS Visual Studio 2010. (I'm guessing the dll was built with Visual Studio, because it came with some VS sample projects.) Any ideas what might be going wrong and how I can get the dll to work with MinGW?

我运行了程序并调试器,崩溃是由对错误地址的调用导致的.这是程序崩溃前的最后四行反汇编:

I ran the program and a debugger, and the crash results from a call to a bad address. Here is the last four lines of disassembly, before the program crashes:

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中的某个位置,第二个调用使程序崩溃.有人能理解吗?

The first call goes to somewhere in msvcrt.dll, the second call crashes the program. Can anyone make sense of this?

推荐答案

不幸的是,有许多细微的差异有关各种编译器如何实现这些所谓的 standard 调用约定的信息.

Unfortunately there are many subtle differences in how the various compilers implement these so called standard calling conventions.

即使使用标准的调用约定将接口定义为extern"c",我也遇到了类似的问题,使Borland C ++编译器可以调用Microsoft DLL.

I had similar problems getting the Borland C++ compiler to call a Microsoft DLL even though the interface was defined as extern "c" using a standard calling convention.

在我的情况下,代码实际上运行了入口点,但返回失败,因为两个编译器无法就如何处理位于堆栈中的返回地址达成共识.

In my case the code actually ran the entry point but it failed on return because the two compilers could not agree on how to handle the stack located return address.

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

Like, you my problems went away when the exact same code was re-compiled with the Microsoft c/c++ compiler.

编辑:该页面具有Mind编译器正在生成的汇编程序可以用来对stdcall进行低级描述.

This page has a low level description of stdcall which you could use to campare with the assembler that the MinGW compiler is producing.

这篇关于链接到C ++中的DLL-相同的代码适用于Visual Studio,但不适用于MinGW的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆