我正在尝试从DLL导出类。我这样做了这篇文章:http://www.codeproject.com/Articles/28969/HowTo-Export-C-classes-from-a-DLL
“成熟”方法表明,使用抽象类,所以我有:
// Header
class IFoo{
public:
virtual int getBar() = 0;
}
class Foo: public IFoo {...}
DLLEXPORT IFoo* Create();
DLLEXPRT void Free(IFoo* inst);
//DLL cpp
IFoo* Create(){ return new Foo; }
void Free(IFoo* inst){ delete inst; }
让我感到困惑的是:如果我没有虚拟析构函数,那么delete inst
将不会调用Foos析构函数并可能泄漏内存。我该怎么办呢?文章没有给出答案。
使用virtual ~IFoo(){}
是不可能的,因为它会向IFoo添加一个实现,这会导致问题(在文章中对内联虚函数的问题的答案中解释)并且virtual ~IFoo() = 0;
失败并带有链接器未定义的符号~IFoo
安全的方法是什么?如何实现免费/发布功能?
答案 0 :(得分:3)
首先,请注意,该问题特定于Visual Studio对DLL的处理。 GCC和Clang都有一个稳定的ABI(Itanium ABI),它保证了用不同版本编译的库的兼容性。
现在,如前所述,您在这里遇到的问题是ABI不稳定,但ABI的部分是稳定的(虚拟表格布局),否则所提出的策略根本不起作用。
因此,简单地使用virtual
析构函数应该可行。由于通过虚拟表进行调用,因此不存在名称重整问题。
另外,请注意,在现代C ++中,返回一个原始指针是禁止的,但是名称修改会阻止使用智能指针......
// Foo.h
class Foo {
public:
virtual int get() = 0;
virtual ~Foo();
protected:
Foo() = default;
Foo(Foo&&) = default;
Foo(Foo const&) = default;
Foo& operator=(Foo) = default;
};
// WARNING: immediately capture this Foo* in a smart pointer,
// or suffer from memory leak (and worse).
Foo* createFoo(); // factory behind
// Foo.cpp
Foo::~Foo() {} // not inline