是否可以使用std :: unique_ptr来管理DLL资源?

Che*_* OT 9 c++ dll raii c++11

LoadLibrary我的项目中有很多,需要FreeLibrary手动调用每个项目LoadLibrary.我想使用std::unique_ptrwith specific deleter来使它自动释放我的dll资源.

这就是我想要定义的内容:

std::unique_ptr<HMODULE, BOOL(*)(HMODULE)> theDll(LoadLibrary("My.dll"), FreeLibrary);
Run Code Online (Sandbox Code Playgroud)

但编译器抱怨类型不匹配.我发现它期望*HMODULELoadLibrary.这std::unique_ptr<A>A*是它的指针类型.看起来我仍然需要定义一个新类来管理DLL资源(LoadLibrary在构造函数和FreeLibrary析构函数中).

有可能std::unique_ptr<A>只是期望A它的指针类型?

更新,

以下是新类的优缺点,并使用std :: unique_ptr,从答案中总结出来.

创建另一个dll管理类,

优点:

  • 完全可控以自定义DLL语义.
  • 将DLL相关部分隔离到一个具有一个职责的类中.
  • 如果需要更多DLL功能,如暴露符号,则易于扩展.

缺点:

  • 需要重建RAII部分已经完成了stadard自动指针.
  • 在RAII部分有机会犯错.
  • 需要声明一个新类.

std::unique_ptr与自定义删除器一起使用,

优点:

  • 无需申报另一个班级.
  • 重用RAII部分unique_ptr.
  • 也许move semantics防止DLL模块实例被复制?

缺点:

  • Dll资源语义可能不适合标准自动指针,并且容易出错?
  • 模板参数unique_ptr很复杂,很难找到错误的位置.
  • HMODULEvoid*,无类型,可能是与unique_ptr集成的问题?

如果我错了,请在评论时纠正我.

Nik*_*lai 6

根据这个页面,HMODULE是HINSTANCE,HINSTANCE是HANDLE,HANDLE是PVOID,PVOID是无效*.这意味着HMODULE是指针类型.所以以下应该有效:

std::unique_ptr<std::remove_pointer_t<HMODULE>, BOOL(*)(HMODULE)> theDll(LoadLibrary("My.dll"), FreeLibrary);
Run Code Online (Sandbox Code Playgroud)

  • 您还可以将“BOOL(*)(HMODULE)”替换为“decltype(&amp;::FreeLibrary)”。 (3认同)

Eri*_*c Z 5

如果您使用它来管理未引用的资源,则需要提供相应的::pointer类型.这是第一个模板参数.unique_ptrTT*Tunique_ptr

如果::pointer未定义任何类型,T*则使用.在你的情况下,HMODULE*这是错的.

struct tLibraryDeleter
{
  typedef HMODULE pointer;
  void operator()(HMODULE h) { FreeLibrary(h); }
};

std::unique_ptr<HMODULE, tLibraryDeleter>(::LoadLibraryA("My.dll"));
Run Code Online (Sandbox Code Playgroud)

看看这里这里.

  • 我建议你重新考虑一下你在说什么.我不知道为什么以及如何将这个定义良好的自定义删除器视为"奇怪且容易出错".如果你真的这么想,至少告诉我们它怎么会出问题.如果您有任何疑虑,请查看[here](http://en.cppreference.com/w/cpp/memory/unique_ptr)和[here](http://stackoverflow.com/questions/12184779/使用-stdunique-PTR换窗型手柄).事实上,你正在重新发明容易出错的车轮. (4认同)
  • 是的,目前我只需要 Windows 平台上 dll 资源的自动释放功能。如果我决定为 dll 扩展更多功能或使其更通用,我会考虑将其移至专用类中。谢谢。 (2认同)