【问题标题】:How to create a shared_ptr in dll and export it via a factory function?如何在 dll 中创建 shared_ptr 并通过工厂函数将其导出?
【发布时间】:2014-06-02 11:35:15
【问题描述】:

我有这段代码:

class DLL_API MyClassWrapper
{
private:

    MyClass * m_myClass;

public:
    MyClassWrapper(SIZE inputSize);
    ~MyClassWrapper();
     inline int OutputSize();

}
typedef  std::shared_ptr<MyClassWrapper> MyClassWrapperPtr;

extern "C"
{
     DLL_API MyClassWrapperPtr CreatreMyClassWrapper(SIZE inputSize)
     {
          return std::make_shared<MyClassWrapper>(inputSize);
      }
}

但它不起作用,出现错误:

Error   1   error C2526: CreatreMyClassWrapper: C linkage function cannot return C++ class 'std::shared_ptr<_Ty>'   

我了解问题所在,但我该如何解决?

我可以看到的选项是:

1- 不要传递共享指针。这意味着DLL用户应该在使用后删除指针。

2- 不要使用 extern "C" : 这意味着我必须使用重命名。

还有其他解决办法吗?

【问题讨论】:

  • 也许从函数返回一个指针并添加另一个(内联?)函数将指针包装成共享指针?
  • 模板永远不应该在公共 Dll 接口中使用。返回普通指针并将 Release 函数添加到删除它的 Dll 中。不要期望智能指针功能可以与 C 客户端一起使用。
  • @user1781290 如何确保删除 dll 中的指针?
  • @AlexFarber:那么我的用户应该很聪明地删除指针。有什么方法可以不要求用户删除指针吗?
  • 类实例应该在创建它的同一个 Dll 中删除。如果客户端没有释放它们,您可以决定在 Dll 中跟踪所有创建的实例并在必要时释放它们。何时执行此操作 - 这取决于您的程序逻辑。但是如果你决定为 C 客户端编写一个包装器,你怎么能将智能指针传递给这样的客户端呢?这是纯 API 接口,客户端可能是从 Assembly 到 .NET 或 Java 的所有内容。再次 - 客户端不应该删除类实例,它应该调用您的 Release 函数。

标签: c++ dll shared-ptr


【解决方案1】:

直截了当,从 C 函数返回 C++ 对象 - 只需通过输出参数返回它:

extern "C"
{
     DLL_API void CreatreMyClassWrapper(SIZE inputSize, SomeClass* outputPtr)
     {
          *outputPtr = SomeClass(....);
     }
}

在你的例子中SomeClass == MyClassWrapperPtr,所以:

extern "C"
{
     DLL_API void CreatreMyClassWrapper(SIZE inputSize, MyClassWrapperPtr* outputPtr)
     {
          *outputPtr = make_shared<MyClassWrapper>(inputSize);
     }
}

但是考虑稍微改变一下你的界面,因为在当前的情况下你需要确保你的应用程序和 DLL 应该使用相同的编译器、链接器、设置、库...*

您可能希望从您的 DLL 中导出 CreateDelete,以确保在您的 DLL 中进行内存管理(这是基于此 answer

DLL

extern "C"
{
     DLL_API MyClassWrapper* CreateMyClassWrapper(SIZE inputSize)
     {
          return new MyClassWrapper(inputSize);
     }
     DLL_API void DeleteMyClassWrapper(MyClassWrapper* wrapper)
     {
          delete wrapper;
     }
}

应用程序

     shared_ptr<MyClassWrapper> myClassWrapper(CreateMyClassWrapper(inputSize), 
                                               DeleteMyClassWrapper);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-09-24
    • 1970-01-01
    • 1970-01-01
    • 2022-06-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多