Я пытаюсь создать класс, совместимый с компилятором, в 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
Может ли кто-нибудь объяснить мне это поведение, пожалуйста?
Спасибо.
ctr()
с отладчиком, который почти сразу скажет вам, в чем проблема. Мне также не совсем понятно, где ваше утверждение о доступе к динамически выделенному производному классу с виртуальными методами через абстрактный базовый интерфейс квалифицируется как POD-что угодно в C++. - person WhozCraig   schedule 14.05.2013Tester
не является POD. - person Michael Burr   schedule 14.05.2013TesterImp::test()
состоит всего из 10 строк ассемблера, так что, вероятно, это не должно быть слишком болезненным. - person Michael Burr   schedule 14.05.2013this
в стеке — MSVC ожидает его вecx
(что делает MinGW 4.7.0 и более поздние версии). - person Michael Burr   schedule 14.05.2013