I came across this article on Code Project that talks about using an abstract interface as an alternative to exporting an entire class from a C++ D开发者_StackOverflow中文版LL to avoid name mangling issues. The author has a Release()
method in his interface definition that is supposed to be called by the user to free the class object's resources after using it. To automate the calling of this method the author also creates an std::auto_ptr<T>
-like class that calls the Release()
method before deleting the object.
I was wondering whether the following approach would work instead:
#include <memory>
#if defined(XYZLIBRARY_EXPORT) // inside DLL
# define XYZAPI __declspec(dllexport)
#else // outside DLL
# define XYZAPI __declspec(dllimport)
#endif // XYZLIBRARY_EXPORT
// The abstract interface for Xyz object.
// No extra specifiers required.
struct IXyz
{
virtual int Foo(int n) = 0;
//No Release() method, sub-class' destructor does cleanup
//virtual void Release() = 0;
virtual ~IXyz() {}
};
// Factory function that creates instances of the Xyz object.
// Private function, do not use directly
extern "C" XYZAPI IXyz* __stdcall GetXyz_();
#define GetXyz() std::auto_ptr<IXyz>( GetXyz_() )
Of course, GetXyz()
can be a global function defined in the header instead of a #define
. The advantage to this method would be that we don't need to cook up our own derivative of auto_ptr
that calls the Release()
method.
Thanks for your answers, Ashish.
by doing this, you risk calling delete (in your process, within auto_ptr's destructor) on an object that is not created by the matching call to new() (that is done inside the factory function, hence inside the dll). Trouble guaranteed, for instance when your dll is compiled in release mode while the calling process in debug mode.
The Release() method is better.
This is exactly how COM works. Avoiding re-inventing this wheel if you already target the Win32 API. Using smart pointers to store COM interface pointers is very common in Windows programming, their destructor calls the Release() method. Take a peek at the MSDN docs for _com_ptr_t and CComPtr for ideas.
The restriction you face if this is a public API is the CRT that the different modules will be linked against and that the CRT that creates the object also needs to be the one to delete it.
There will be a mess if you don't choose the right CRT Anything sharing memory management should use CRT (or other memory allocation) as external lib - ie. MSVC: Multi-threaded DLL (/MD)
Given that, then there is not even a need for the subclass to achieve your purpose.
精彩评论