应由库或客户端代码删除已加载库中的对象实例

Should object instance from loaded library be deleted by the library or from client code?

本文关键字:加载 对象 实例 码删除 客户端 代码      更新时间:2023-10-16

在我的解决方案中,我通过导入的函数从动态加载的DLL中获取几个对象指针:

DLL 端

extern "C" 
    API_EXPORT PluginBase* createInstance(const string& typeName)
{
    return TypeRegistry::instance().getTypeInstance(typeName);
}

客户端

HMODULE lib = LoadLibrary("theDll.dll");
void* proc = GetProcAddress(lib, "createInstance");
if(proc)
{           
    auto createFunc = reinterpret_cast<T* (*)(const string&)>(proc);
    shared_ptr<PluginBase> instancePtr(createFunc(theType));  
}

实际的问题是,什么被认为更正确和/或更方便?

  • 提供额外的导出函数,如releaseInstance(PluginBase*)到DLL库并使用它。
  • 从客户端代码中删除实例指针。

问候

提供删除器。

它消除了关于用户应该如何删除对象(deletefree(毕竟它来自extern "C"电话)?

此外,在某些版本的 Visual Studio 中,运行时库的工作方式可能意味着您无法在一个模块中delete对象,而该对象在另一个模块中new

不过,比任何一种选择(IMO)都好:返回已使用适当的删除程序初始化的shared_ptr

为了良好的封装/秘密隐藏,我更喜欢第一种方法(即提供自定义删除方法)。您可以获得更大的灵活性,例如,如果对象创建成本很高,则可能会有一些对象池,createInstance 方法从中返回一个空闲对象。与其实际删除对象,不如在发布时进行简单的重置就足够了。

根据您的方案,可能很清楚您永远不需要这样的东西(如果您只在少数地方使用此方法)。尽管如此,由于这种封装不会带来很多复杂性,因此在大多数情况下,我可能更喜欢第一种方法。

创建的详细信息只有 DLL 知道。

客户端无法知道必须执行哪些操作才能正确处置对象。

预计 DLL 将提供正确释放对象的方法,即使在创建时没有特殊原因导致客户端不应自行删除它。

创建和释放的方式将来可能会更改,如果在早期版本中没有提供释放对象的方法,则客户端的代码将中断。