问题
I'm trying to export a class from a DLL. I read this article on doing so: http://www.codeproject.com/Articles/28969/HowTo-Export-C-classes-from-a-DLL
The "mature" approach suggest, that an abstract class is used, so I have:
// 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; }
What puzzles me: If I don't have a virtual destructor, then delete inst
won't call Foos destructor and may leak memory. How am I supposed to handle that? The article does not give an answer to that.
Using virtual ~IFoo(){}
is not possible, as that adds an implementation to IFoo which causes problems (explained in a answer to a question in the article for an inline virtual function) and virtual ~IFoo() = 0;
fails with a linker error on the undefined symbol ~IFoo
What is the safe way to go? How should the Free/Release functions be implemented?
回答1:
First of all, let's note that the issue is specific to Visual Studio's handling of DLLs. GCC and Clang both have a stable ABI (Itanium ABI) which guarantees the compatibility of libraries compiled with different versions.
Now, as mentioned, the issue you face here is ABI instability, however parts of the ABI are stable (the virtual table layout) otherwise the strategy presented would simply not work.
Therefore, simply having a virtual
destructor should work. There will be no name mangling issue because of the call via the virtual table.
Also, note that in modern C++ returning a raw pointer is a no-no, but name mangling prevents the use of a smart pointer...
// 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
来源:https://stackoverflow.com/questions/32444520/how-to-handle-destructors-in-dll-exported-interfaces