Visual Studio — C ++ двоичная совместимая инициализация dll POD члена класса вызывает сбой

Я пытаюсь сделать совместимый с компилятором класс в dll, созданной с помощью mingw, который можно использовать в приложении Windows VS. Моя проблема в том, что мой класс падает в тот момент, когда он пытается инициализировать переменную-член, когда функция вызывается из программы VS. Использование STL или создание локальных переменных в одних и тех же функциях работает нормально.

Необработанное исключение в 0x6BEC19FE (test.dll) в ConsoleApplication2.exe: 0xC0000005: Место записи нарушения прав доступа 0x154EB01E.

Простая демонстрация:

Код DLL

#include <iostream>

class Tester
{
public:

virtual void test() = 0;
};

class TesterImp : public Tester
{
public:
TesterImp(){}
~TesterImp(){}

virtual void test() {
int test = 5; // fine
m_test = 5; // access violation
}

private:

int m_test;

};

extern "C"{
__declspec (dllexport) Tester* Create()
{
return new TesterImp();
}
}

Основная программа, которая загружает dll и вызывает тестовую функцию:

#include <iostream>
#include <Windows.h>

class Tester
{
public:

virtual void test() = 0;
};

typedef Tester* (*createPtr)();

int main(int argc, const char **argv, char * const *envp) {

HINSTANCE hGetProcIDDLL = LoadLibraryA("test.dll");

if (hGetProcIDDLL == NULL) {
std::cout << "could not load the dynamic library" << std::endl;
return EXIT_FAILURE;
}

createPtr ctr = (createPtr)GetProcAddress(hGetProcIDDLL, "Create");
if (!ctr) {
std::cout << "could not locate the function" << std::endl;
return EXIT_FAILURE;
}

std::cout << "dll loading success!" << std::endl;

Tester* testf = ctr();

std::cout << "Got test class" << std::endl;

testf->test(); // crash if the member variable is referenced, fine otherwise with local variable initialization or STL use inside the function

std::cout << "Running dll functions success!" << std::endl;

return 0;
}

Основная программа скомпилирована в режиме отладки с VS2012, а dll собрана с использованием g ++ из mingw —

g ++ -shared -o test.dll test.cpp

Может кто-нибудь объяснить мне это поведение, пожалуйста?

Спасибо.

2

Решение

Вы, вероятно, используете более старую версию MinGW. До 4.7.0 (я думаю), MinGW прошел this указатель на стек, который отличается от MSVC thiscall конвенция о прохождении this указатель в ecx,

Начиная с 4.7.0, MinGW использует то же самое thiscall Соглашение о вызовах как MSVC.

Я также могу получить пример TesterImp::test() функция, которая будет вызвана из MSVC успешно, пометив оба Tester::test() а также TesterImp::test() в test.cpp с __attribute__((thiscall)) приписывать. Это работало с MinGW 4.6.2, что приводило к сбою без использования атрибута.

1

Другие решения

Других решений пока нет …