我正在开发一个带有插件系统的程序,它允许用户以DLL文件的形式开发自己的模块。 模块应该使用在由应用程序的所有组件导入的DLL中定义的对象。下面是一个示例对象将是什么样子:导出构造函数的风险造成堆损坏
#include <boost/system/api_config.hpp>
#if defined BOOST_WINDOWS_API
#ifdef EXPORT
#define API __declspec(dllexport)
#else
#define API __declspec(dllimport)
#endif
#else
#define API
#endif
class A
{
public:
API A();
API virtual ~A();
};
所有DLL静态建(用自己的CRT),并具有完全相同的编译标志。我知道通过DLL边界交换对象可能会变得毛茸茸的,所以我几乎在任何地方都使用boost::shared_ptr
。围绕对象构造函数有一个困难:如果我在堆栈上创建对象(来自不同的DLL),则所有事情都按预期工作。但是,如果我使用运算符new
,则会删除该对象时堆损坏。
A a; // Works fine, no problem when the object goes out of scope.
A* b = new A();
delete b; // Causes heap corruption!
这是什么方法?如果我必须在对象的DLL中定义一个方法,例如A* A::create() { return new A(); }
,我觉得代码的可读性会降低。在最糟糕的情况下,我想让new
运营商保持私密,以确保用户不会使用它。
我不知道我得到您的问题。从你展示的内容来看,你的DLL里没有任何东西,因为所有的函数都是“inline”的。你通常不需要在内联函数或模板上使用'__declspec'。 –
如果我更改代码,以便构造函数和析构函数不是内联的,它对我来说很有用。您确定您为DLL和使用它的代码都指定了兼容的链接器选项吗? (特别是,你可能需要系统地使用'/ MD'或'/ MDd',没有它,你会看到这样的问题。) –
我的构造函数/析构函数实际上不是内联函数,我编辑了文章以反映它。我确认我得到了堆腐败。我的构建标志确实是'/ MT'和'/ MTD',但我不想改变它们。 – executifs