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;
}
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?
EDIT: 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
The first call goes to somewhere in msvcrt.dll, the second call crashes the program. Can anyone make sense of this?
Unfortunately there are many subtle differences in how the various compilers implement these so called standard calling conventions.
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.
Like, you my problems went away when the exact same code was re-compiled with the Microsoft c/c++ compiler.
Edit: This page has a low level description of stdcall which you could use to campare with the assembler that the MinGW compiler is producing.
Different compilers do different name mangling. You need to compile all of a C++ project with a compatible compiler for it to link properly.