代码之家  ›  专栏  ›  技术社区  ›  aquila

加载库中的对象实例应该由库删除还是从客户端代码中删除?

  •  1
  • aquila  · 技术社区  · 11 年前

    在我的解决方案中,我通过导入函数从动态加载的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));  
    }
    

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

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

    当做

    3 回复  |  直到 11 年前
        1
  •  1
  •   Sebastian Redl    11 年前

    提供删除器。

    它消除了关于用户应该如何删除对象的任何困惑( delete ? free (它来自 extern "C" 毕竟打电话)?)

    此外,在某些版本的Visual Studio中,运行库的工作方式可能意味着 不能 删去 一个模块中的对象 new 在另一个。

    但比这两个选项都好(IMO):返回 shared_ptr 您已经用适当的删除器初始化了。

        2
  •  1
  •   Philipp    11 年前

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

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

        3
  •  1
  •   ThunderGr    11 年前

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

    客户端不知道他们必须做什么才能正确处理对象。

    可以预期,DLL将提供一种适当处理对象的方法,即使在创建时没有特殊原因说明客户端不应自行删除该对象。

    如果在早期版本中没有提供处理对象的方法,那么创建和处理对象的方式将来可能会发生变化,并且客户端的代码将中断。