我在使用C ++编写的DLL时遇到问题。有一些非常奇怪的行为正在发生,我自己无法解决。
很难准确描述发生了什么,但我会尽我所能。基本上我在我的DLL中有一个类,它有一个私有属性和一个公共构造函数。 当我初始化此类然后退出程序时,我收到错误。
“运行时检查失败#2 - 围绕变量'test'进行堆栈 损坏“
我在这里 2个项目:
我把这个错误归结为最简单的可重复形式,试图缩小可能的原因,下面你会找到我的代码。
项目“testdll”,文件testdll.h:
#include <string>
class testdll
{
public:
__declspec(dllexport) testdll(); // Empty but same error if prams are used.
private:
std::string _var;
};
项目“testdll”,文件testdll.cpp:
#include "testdll.h"
testdll::testdll()
{
}
项目“test”,文件testdll.h:
#include <string>
class testdll
{
public:
__declspec(dllimport) testdll();
};
项目“测试”,文件stdafx.h:
#pragma once
#include "targetver.h"
#include <tchar.h>
项目“测试”,文件test.cpp:
#include "stdafx.h"
#include "testdll.h"
int _tmain(int argc, _TCHAR* argv[])
{
testdll test;
return 0;
}
如果您愿意,我可以使用您选择的存档格式向您发送 Visual C ++ 2010 解决方案文件。请帮忙!我不知道发生了什么。
可选信息: 语言(或软件):C ++
已经尝试过: 删除构造函数定义,它既可以使用但不是可用的解决方案,也不能解释问题。同时使我的所有私有属性成为指针,但我不应该这样做。
答案 0 :(得分:1)
您正在使用两个头文件,它们不会声明同一个类。一个有std :: string成员,另一个没有。这非常非常糟糕,编译器没有为堆栈帧上的对象保留足够的空间。这是运行时错误告诉你的。非常好的功能btw,这种错误非常难以诊断。
你可能已经进入了这个pickle,因为你只将__declspec(dllexport)应用于构造函数而不是整个类。您需要编写头文件,以便它可以被您的dll项目和用于您的exe项目。这应该是这样的:
#undef DLLEXPORT
#ifdef BUILDING_MYDLL
# define DLLEXPORT __declspec(dllexport)
#else
# define DLLEXPORT __declspec(dllimport)
#endif
class DLLEXPORT testdll
{
public:
testdll();
private:
std::string _var;
};
右键单击DLL项目,属性,C / C ++,预处理器,预处理器定义。附加BUILDING_MYDLL
删除exe项目目录中的testdll.h文件。设置C / C ++,General,Additional Include Directories设置,以便编译器可以在testdll项目目录中找到标题(如.. \ testdll)
答案 1 :(得分:0)
从DLL中导出类和类成员非常非常脆弱,正如您刚刚发现的那样。如果库和客户端都没有使用完全相同的类布局,这取决于所有类型的编译器设置,那么事情就会非常糟糕。
在您的情况下,您可能在std::string
内使用了不兼容的class testdll
版本。也许一个编译用于调试,一个用于发布。或者一个是使用静态运行时库,另一个是使用DLL运行时。谁能说?
无论如何,只要从DLL导出C ++功能,就可以锁定自己的编译器版本和设置。这是一场维护噩梦。
使用仅限v-table的基类或C兼容的包装函数。