c++二进制兼容dll POD类成员初始化导致崩溃
C++ binary compatible dll POD class member initialization causes crash
我试图在一个可以在Windows VS应用程序中使用的mingw构建的dll中创建一个编译器间兼容的类。我的问题是,当从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并调用test函数的主程序:
#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
谢谢。
您可能使用的是旧版本的MinGW。直到4.7.0(我认为),MinGW在堆栈上传递this
指针,这与MSVC在ecx
中传递this
指针的thiscall
惯例不同。
从4.7.0开始,MinGW使用与MSVC相同的thiscall
调用约定。
我还可以通过使用__attribute__((thiscall))
属性在test.cpp
中标记Tester::test()
和TesterImp::test()
来成功地从MSVC中调用示例TesterImp::test()
函数。这适用于MinGW 4.6.2,如果不使用该属性,将导致崩溃。
相关文章:
- 为什么在C++中首先初始化成员类
- 是否可以防止省略聚合初始化成员?
- 正在复制具有未初始化成员的结构
- 使用大括号或括号初始化成员变量
- C++结构:强制初始化成员?
- C++中未初始化成员布尔变量的默认值是多少?
- 使用默认值初始化成员引用
- 在构造函数中初始化成员时,是否应该在成员上使用 std::move?
- C++使用 { } 初始化成员变量
- 如何根据构造函数参数使用超类类型初始化成员变量?
- OpenGL C++:VBO 的结构包装器不会初始化成员
- 有没有办法在Brace中初始化成员
- 从现有 istream 或类本身创建的 istream 初始化成员 istream
- 从其后声明的另一个成员数据初始化成员数据是否为未定义行为
- 通常应用方法,使用带有构造函数委托的 SFINAE 通过类模板的构造函数初始化成员
- 如何在嵌套类中初始化成员?C
- 是否可以在构造函数主体中初始化成员变量,而不是初始值设定项列表
- 编译器错误,因为构造函数必须显式初始化成员
- 如何使用成员函数初始化成员函数指针
- C 如何使用隐藏的默认构造函数初始化成员