0

我在使用 C++ 编写的 dll 时遇到问题。发生了一些我自己无法解决的非常奇怪的行为。

很难准确描述发生了什么,但我会尽力而为。基本上我的 DLL 中有一个类,它有一个私有属性和一个公共构造函数。当我初始化这个类然后退出程序时,我得到一个错误。

“运行时检查失败 #2 - 变量 'test' 周围的堆栈已损坏”

我在这里有2 个项目

  1. 名为“ testdll ”的 DLL。
  2. 名为“ test ”的控制台测试程序。

我已将此错误归结为最简单的可重现形式,以尝试缩小可能的原因,您将在下面找到我的代码。

项目“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()
{
}

项目“测试”,文件 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++

已尝试: 删除构造函数定义,该方法有效但不是可用的解决方案,也不能解释问题。也可以将我所有的私有属性变成指针,但是我不应该这样做。

4

2 回答 2

1

您正在使用两个头文件,它们没有声明同一个类。一个有一个 std::string 成员,另一个没有。这非常非常糟糕,编译器没有为堆栈帧上的对象保留足够的空间。这就是运行时错误告诉您的内容。非常好的功能顺便说一句,这种错误很难诊断。

您可能进入了这个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)

于 2012-04-29T10:07:32.377 回答
0

正如您刚刚发现的那样,从 DLL 导出类和类成员非常脆弱。如果库和客户端不使用完全相同的类布局,这取决于各种编译器设置,那么事情就会失败。

在您的情况下,您可能正在使用不兼容的std::stringinside版本class testdll。也许一个是为调试而编译的,一个是为发布而编译的。或者一个是使用静态运行时库,另一个是 DLL 运行时。谁能说?

无论如何,一旦您从 DLL 导出 C++ 功能,您就会将自己锁定在该编译器版本和设置中。这是维护的噩梦。

使用仅 v-table 基类或与 C 兼容的包装函数。

于 2012-04-29T06:19:22.907 回答