如何从dll正确返回std :: list

时间:2015-03-01 19:40:59

标签: c++ visual-c++ dll

该项目具有以下结构: 1. Dll - 具有核心逻辑和类层次结构 2. exe - 控制台应用程序,它处理命令行并启动算法 3. Dll - 测试,就像一个单元测试工具包 - 硬编码填充第一个Dll中的对象集合,并将集合传递给exe控制台进行处理

所以Dll第3点应该返回集合(例如std :: list),该集合包含多态对象,然后应该存储指针, 我更喜欢使用std :: unique_ptr而不是原始指针

我看到unique_ptr仅支持移动语义,我正在使用emplace_back成员填充列表。 但是返回std :: list>存在问题。来自Dll的与MSVC类导出技术相关的集合

如果我理解这一点: 在dll和exe项目之间共享标题应该包含这样的东西,其中EXP_DLL应该为Dll定义而未定义为exe

 #ifdef EXP_STL
 #    define DECLSPECIFIER __declspec(dllexport)
 #    define EXPIMP_TEMPLATE
 #else
 #    define DECLSPECIFIER __declspec(dllimport)
 #    define EXPIMP_TEMPLATE extern
 #endif

 EXPIMP_TEMPLATE template class DECLSPECIFIER std::list<std::unique_ptr<MyBassClass>>;

 std::list<std::unique_ptr<MyBassClass>> DECLSPECIFIER make_test_array();

这个定义:

 EXPIMP_TEMPLATE template class DECLSPECIFIER std::list<std::unique_ptr<MyBassClass>>;

引发错误

  

C2280:标准::的unique_ptr&GT; ::的unique_ptr(常量   的std ::的unique_ptr&LT; _Ty,性病:: default_delete&LT; _Ty&GT;&GT; &amp;)':试图   引用已删除的功能

我看到尝试调用unique_ptr的复制ctor(当然,已删除)

你能否为我澄清这些问题:

  1. 实例化模板的导出声明如何在此处调用复制ctor?
  2. 您能否建议解决方案如何避免这种情况?

1 个答案:

答案 0 :(得分:1)

假设满足以下条件:

  1. 解决方案中的所有项目都链接相同的运行时DLL(/ MD选项)
  2. 类MyBaseClass归因于DECLSPECIFIER。
  3. 类MyBaseClass在make_test_array声明之前完全定义。
  4. 您根本不能导出模板专业化。只需删除第EXPIMP_TEMPLATE template class ...行即可。 将内联std :: list和std :: unique_ptr代码。 您将收到警告C4251,忽略它。

    当您尝试导出std::list专精时,所有 std::list<T>方法都会被实例化。其中一些(例如赋值运算符)要求T是可复制的。这就是为什么不能编译unique_ptr的专业化的原因。