我将尝试举例说明我的问题。
我有以下课程:
__declspec(dllexport) class myclass
{
public:
int a;
int b;
myclass() {};
virtual ~myclass() {};
// ~myclass() {};
};
myclass在DLL内部使用,该类仅包含类Test的定义(实际上,该类只是方法foo1和foo2]的接口>):
或foo2填充的向量。class Test { public: void foo1 (std::vector<myclass>& val); std::vector<myclass> foo2 (); }; extern "C" { __declspec(dllexport) bool foo1(std::vector<myclass>& val) { val.clear(); myclass tmp; val.push_back(tmp); val.push_back(tmp); val.push_back(tmp); //just an example! return true; } __declspec(dllexport) std::vector<myclass> foo2() { std::vector<myclass> val; myclass tmp; val.push_back(tmp); val.push_back(tmp); val.push_back(tmp); //just an example! return val; } }
主应用程序打开DLL并调用接口方法以获得由方法foo1
或foo2),当我尝试清除(或执行任何其他操作时,都出现“访问冲突读取XXXX”错误),然后在tmp矢量上卸载dll。typedef void (*FNPTR1)(std::vector<myclass>& val); typedef std::vector<myclass> (*FNPTR2)(); int main() { if (0) { HINSTANCE hInst = LoadLibrary(L"C:\\software\\mydll.dll"); if (!hInst) { std::cout << "\nCould Not Load the Library"; return EXIT_FAILURE; } FNPTR1 fn = (FNPTR1)GetProcAddress(hInst, "foo1"); if (!fn) { std::cout << "\nCould not locate the function"; return EXIT_FAILURE; } std::vector<myclass> tmp; fn(tmp); FreeLibrary(hInst); tmp.clear(); //crash here! } if (1) { HINSTANCE hInst = LoadLibrary(L"C:\\software\\mydll.dll"); if (!hInst) { std::cout << "\nCould Not Load the Library"; return EXIT_FAILURE; } FNPTR2 fn = (FNPTR2)GetProcAddress(hInst, "foo2"); if (!fn) { std::cout << "\nCould not locate the function"; return EXIT_FAILURE; } std::vector<myclass> tmp; tmp = fn(); FreeLibrary(hInst); tmp.clear(); //crash here! } return 1; } }
[不幸的是,在两种情况下(使用foo1
仅当myclass
的析构函数是虚拟的时,才会发生此问题。在我的应用程序中,myclass
是自动生成的,不允许我修改析构函数定义。但是,如果该级别存在某种解决方案,我可以自由修改dll接口方法(即foo1 / foo2)。我还想知道是否有可能告诉系统将tmp
向量用于主程序的堆,而不是.dll使用的堆。我目前正在使用Visual Studio c ++ 2017,可以使用C ++ 11标准(或更高版本)
谢谢您的帮助。
回答以下评论:
关于关于myclass
1-具有标准析构函数的myclassbase和具有标准析构函数的myclass->确定
2-具有标准析构函数的myclassbase和具有虚拟析构函数的myclass->崩溃
3-具有虚拟析构函数的myclassbase和具有标准析构函数的myclass->崩溃
4-具有虚拟析构函数的myclassbase和具有虚拟析构函数的myclass->崩溃
因此,我可以得出结论,仅存在一个虚拟析构函数就足以产生问题。
我将尝试通过一个例子来解释我的问题。我有以下类:__declspec(dllexport)类myclass {public:int a; int b;我的课() {};虚拟〜myclass(){}; //〜...
最后,我在计算机前,有时间仔细检查您的代码。