【发布时间】:2015-07-29 06:32:52
【问题描述】:
我的项目中有很多LoadLibrary,需要为每个LoadLibrary手动调用FreeLibrary。我想使用带有特定deleter 的std::unique_ptr 使其自动释放我的dll 资源。
这就是我想要定义的:
std::unique_ptr<HMODULE, BOOL(*)(HMODULE)> theDll(LoadLibrary("My.dll"), FreeLibrary);
但是编译器抱怨类型不匹配。我发现它期望来自LoadLibrary 的*HMODULE。那就是std::unique_ptr<A> 将期望A* 作为它的指针类型。看来我仍然需要定义一个新类来管理 DLL 资源(构造函数中的LoadLibrary 和析构函数中的FreeLibrary)。
是否可以让std::unique_ptr<A> 只期望A 作为其指针类型?
更新,
以下是新类和使用 std::unique_ptr 的优缺点, 从答案中总结出来。
创建另一个dll管理类,
优点:
- 完全可控,可针对 DLL 语义进行自定义。
- 将与 DLL 相关的部分隔离到一个具有一个职责的类中。
- 如果需要 DLL 的更多功能(例如公开符号),可以轻松扩展。
缺点:
- 需要重建 RAII 部分,标准自动指针已完成。
- 有机会在 RAII 部分出错。
- 需要声明一个新类。
将std::unique_ptr 与自定义删除器一起使用,
优点:
- 无需声明另一个类。
- 重复使用
unique_ptr的 RAII 部分。 - 也许
move semantics阻止了 DLL 模块实例被复制?
缺点:
- Dll 资源语义可能不符合标准自动指针,并且容易出错?
-
unique_ptr中的模板参数很复杂,很难找到错误所在。 -
HMODULE是void*,是无类型类型,与unique_ptr 集成可能有问题?
如果我错了,请在评论中纠正我。
【问题讨论】:
-
老实说,我认为将 DLL 包装在一个类中会更安全一些,因为它会进行错误处理,尽管它最初使用 unique_ptr 看起来很优雅
-
@CyberSpock 完全同意。
-
到目前为止,我发现,我可以测试
theDll.get()是否为空来知道Is LoadLibrary is succeeded?。通过stackoverflow.com/a/11164463/2210478,如果theDll.get()为null,则std::unique_ptr不会在指针上调用deleter。所以我不担心我将 NULL 传递给 FreeLibrary。 -
ATL 提供了一个HANDLE 管理类,CHandle。 msdn.microsoft.com/en-us/library/5fc6ft2t.aspx#chandle__chandle