导出 C++来自 DLL 的类

发布于 2024-09-08 16:30:11 字数 1226 浏览 2 评论 0原文

我在代码项目上发现了这篇文章,其中讨论了使用摘要接口作为从 C++ DLL 导出整个类的替代方案,以避免名称损坏问题。作者在其接口定义中有一个 Release() 方法,用户应该在使用类对象后调用该方法来释放该类对象的资源。为了自动调用此方法,作者还创建了一个类似 std::auto_ptr 的类,该类在删除对象之前调用 Release() 方法。

我想知道以下方法是否可行:

#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_() )

当然,GetXyz() 可以是标头中定义的全局函数,而不是 #define。此方法的优点是我们不需要编写自己的调用 Release() 方法的 auto_ptr 派生类。

感谢您的回答, 阿什什。

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++ DLL 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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

懷念過去 2024-09-15 16:30:11

通过这样做,您可能会冒着调用delete(在您的进程中,在auto_ptr的析构函数中)的风险,该对象不是通过对new()的匹配调用创建的(这是在工厂函数内部完成的,因此是在dll内部完成的)。肯定会出现问题,例如当您的 dll 在发布模式下编译而调用进程在调试模式下时。

Release() 方法更好。

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.

凝望流年 2024-09-15 16:30:11

这正是 COM 的工作原理。如果您已经针对 Win32 API,请避免重新发明这个轮子。使用智能指针存储COM接口指针在Windows编程中很常见,它们的析构函数调用Release()方法。查看 _com_ptr_t 和 CComPtr 的 MSDN 文档以获取想法。

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.

拥抱我好吗 2024-09-15 16:30:11

如果这是一个公共 API,您面临的限制是不同模块将链接到的 CRT,并且创建该对象的 CRT 也必须是删除该对象的 CRT。

如果你没有选择正确的CRT,将会出现混乱
任何共享内存管理的东西都应该使用 CRT(或其他内存分配)作为外部库 - 即。 MSVC:多线程 DLL (/MD)

鉴于此,甚至不需要子类来实现您的目的。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文