Связывание с DLL в C ++ - тот же код работает с Visual Studio, но не с MinGW - PullRequest
0 голосов
/ 13 февраля 2012

Я пытаюсь использовать сторонний dll в проекте MinGW; 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, второй вызов приводит к сбою программы. Кто-нибудь может понять это?

Ответы [ 2 ]

1 голос
/ 13 февраля 2012

К сожалению, существует множество тонких различий в том, как различные компиляторы реализуют эти так называемые стандартные соглашения о вызовах.

У меня были похожие проблемы с получением компилятора Borland C ++ длявызывать Microsoft DLL, даже если интерфейс был определен как extern "c" с использованием стандартного соглашения о вызовах.

В моем случае код фактически выполнял точку входа, но при возврате он не удался, потому что два компилятора не смогли согласоватькак обрабатывать адрес возврата в стеке.

Например, у вас проблемы исчезли, когда тот же код был перекомпилирован с помощью компилятора Microsoft c / c ++.

Редактировать: Эта страница содержит низкоуровневое описание stdcall, которое вы могли бы использовать для разбивки на ассемблере, создаваемом компилятором MinGW.

0 голосов
/ 13 февраля 2012

Разные компиляторы делают разные названия.Вам нужно скомпилировать весь проект C ++ с совместимым компилятором, чтобы он правильно связывался.

...