我正在尝试在使用mingw构建的dll中创建一个可以在Windows VS应用程序中使用的编译器间兼容类。我的问题是,当从VS程序调用函数时,我的类会在尝试初始化成员变量时崩溃。使用STL或在同一函数中创建局部变量可以正常工作。
ConsoleApplication2.exe中0x6BEC19FE(test.dll)的未处理异常: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使用mingw中的g ++构建 -
g ++ -shared -o test.dll test.cpp
有人可以帮我解释一下这种行为吗?
谢谢。
答案 0 :(得分:1)
您可能正在使用较旧版本的MinGW。直到4.7.0(我认为),MinGW在堆栈上传递了this
指针,这与MSVC在thiscall
中传递this
指针的ecx
约定不同。 / p>
从4.7.0开始,MinGW使用与MSVC相同的thiscall
调用约定。
我还可以通过使用TesterImp::test()
属性标记Tester::test()
中的TesterImp::test()
和test.cpp
来成功地从MSVC调用示例__attribute__((thiscall))
函数。这适用于MinGW 4.6.2,这会导致崩溃而不使用该属性。