应由库或客户端代码删除已加载库中的对象实例
Should object instance from loaded library be deleted by the library or from client code?
在我的解决方案中,我通过导入的函数从动态加载的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库并使用它。
- 从客户端代码中删除实例指针。
问候
提供删除器。
它消除了关于用户应该如何删除对象(delete
? free
(毕竟它来自extern "C"
电话)?
此外,在某些版本的 Visual Studio 中,运行时库的工作方式可能意味着您无法在一个模块中delete
对象,而该对象在另一个模块中new
。
不过,比任何一种选择(IMO)都好:返回已使用适当的删除程序初始化的shared_ptr
。
为了良好的封装/秘密隐藏,我更喜欢第一种方法(即提供自定义删除方法)。您可以获得更大的灵活性,例如,如果对象创建成本很高,则可能会有一些对象池,createInstance
方法从中返回一个空闲对象。与其实际删除对象,不如在发布时进行简单的重置就足够了。
根据您的方案,可能很清楚您永远不需要这样的东西(如果您只在少数地方使用此方法)。尽管如此,由于这种封装不会带来很多复杂性,因此在大多数情况下,我可能更喜欢第一种方法。
创建的详细信息只有 DLL 知道。
客户端无法知道必须执行哪些操作才能正确处置对象。
预计 DLL 将提供正确释放对象的方法,即使在创建时没有特殊原因导致客户端不应自行删除它。
创建和释放的方式将来可能会更改,如果在早期版本中没有提供释放对象的方法,则客户端的代码将中断。
相关文章:
- 共享对象、符号、C/C++ 库链接和加载
- ./main:加载共享库时出错:libopencv_highgui.so.4.0:无法打开共享对象文件:没有这样的文件或
- 在 win32 上生成 R 包:无法加载共享对象 (.dll)
- 指向临时对象的自定义迭代器(延迟加载)
- 加载共享库时出错:libbsoncxx.so._noabi:无法打开共享对象文件:没有此类文件或目录
- C++ csv 文件无法正确加载到矢量,它似乎知道对象在那里但不显示它们
- 将文件从 iOS 应用程序加载到 C++ 对象中/<iostream>iOS 上的问题
- 正在加载共享对象:文件中未定义版本Qt_5
- 如何将统一缓冲区对象数组加载到着色器中?
- 加载共享库时出现"错误:libSDL2_mixer-2.0.so.0:无法打开共享对象文件:没有这样的文件或目录
- 加载地址 X 时,对于 Y 类型的对象没有足够的空间
- 通过无符号 char 别名进行对象访问,加载和存储时会发生什么?
- 加载共享库时出错:无法在外部硬件上打开共享对象文件:
- 动态加载要执行的对象文件
- 如何将项目共享"system calls"作为单例对象构建和链接到引导加载程序?
- 在C 中使用DLSYM加载共享对象功能
- 在磁盘上/从磁盘存储/加载C++对象
- c++游戏加载对象/全局对象
- 如何动态加载c++对象并通过包装器接口使用它们
- SWIG:仅使用标头和共享库包装Perl的C++,无法找到可加载对象错误