如何处理DLL导出接口中的析构函数

时间:2015-09-07 18:49:15

标签: c++ dll destructor dllexport pure-virtual

我正在尝试从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

上的错误

安全的方法是什么?如何实现免费/发布功能?

1 个答案:

答案 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
相关问题