如何将 unique_ptr 对象作为参数传递给作为库的类

Posted

技术标签:

【中文标题】如何将 unique_ptr 对象作为参数传递给作为库的类【英文标题】:How to pass unique_ptr object as argument to a class that is a library 【发布时间】:2018-03-24 19:57:09 【问题描述】:

我阅读了与将 unique_ptr 作为参数传递给类构造函数相关的所有问题和答案,这些答案适用于 exe 中的类。但是在这里我试图将一个 unique_ptr 对象传递给一个预编译为静态库的类构造函数。

库中的这个类看起来是这样的,

// Class declaration (in a header file)
class TScreen

   private:
      std::unique_ptr<TProcess> m_process;
   public:
      __fastcall TScreen(int a, std::unique_ptr<TProcess> i_process);
;    

// The constructor definition (in a separate .cpp file)
__fastcall TScreen::TScreen(int a, std::unique_ptr<TProcess> i_process): 
m_process(std::move(i_process)) 
 

我将尝试像这样在 exe 中实例化 TScreen 类,

void TScreen_Main::CallScreen()

   std::unique_ptr<TProcess> objprocess (new TProcess());
   std::unique_ptr<TScreen> objscreen (new TScreen(0, std::move(objprocess)));

我编译了库并将其导入到 exe 中。当我编译exe时,它给了我一个这样的链接错误,

[ilink32 Error] Error: Unresolved external '__fastcall TScreen::TScreen(int, std::unique_ptr<TProcess, std::default_delete<TProcess> >)' referenced from TSCREEN_MAIN.OBJ
[ilink32 Error] Error: Unable to perform link

我也对 boost::shared_ptr 进行了同样的尝试,但它给了我同样的错误。但它适用于原始指针,但不适用于智能指针,我不知道为什么?

提前致谢。

【问题讨论】:

尝试将inline 放在__fastcall 之后。这是一个链接问题。所以,不知何故,这个函数永远不会把它变成一个 obj 文件。即使它可能永远不需要,因为它很容易内联。如果您明确声明它inline,这会告诉链接器,如果它确实需要定义它需要在任何地方发出它,那么该定义将不仅仅是位于某个随机的.obj 文件中。 【参考方案1】:

您的问题是链接问题。现在,我很难说到底发生了什么,因为我从来没有在 Windows 环境中工作过,而链接(虽然非常相似)在 Unix/Linux 和 Windows 环境之间有一些明显的区别。

我的猜测是,如果你明确声明你的构造函数为inline,并声明定义为inline,它就会正常工作。

这假设您将类的声明和定义放在一起表明定义与类一起在头文件中。

当编译器看到它被声明为inline 时,它会在需要它的每个编译单元中发出一个定义。然后链接器应该消除所有重复的定义。

如果您确实在某个 .cpp 文件中定义构造函数,该文件与该类所在的 .hpp 文件分开,并且您将 .cpp 文件编译为 .obj 文件,最终将其编译为 @987654328 @ 或 .dll 在创建可执行文件时链接,那么我不知道问题是什么。如果是这种情况,您应该使用开发环境附带的工具来查看库或 dll 中实际存在哪些符号,因为构造函数定义的符号不存在。

【讨论】:

谢谢你,你的回答让我知道我在找什么。我的构造函数定义在单独的.cpp 中,所以我要查找的关键字不是inline。我必须声明构造函数explicit,现在链接发生了。 @RaviSangar - 这不应该有任何影响。 explicit 与链接或符号可见性无关。它只告诉编译器构造函数不能用于隐式转换,这对于多参数构造函数来说是毫无意义的,因为无论如何它们永远不会(AFAIK)被考虑用于隐式转换。我的猜测是您修改 .cpp 文件会迫使您的 IDE 重新编译并重新生成您的库。 实际上,作为提高代码质量的编码指南,我们声明所有类构造函数explicit,所以我想在尝试您的建议之前添加它并且它有效。我还尝试在同一个文件中添加带有 inline 关键字的声明和定义,这也很有效。

以上是关于如何将 unique_ptr 对象作为参数传递给作为库的类的主要内容,如果未能解决你的问题,请参考以下文章

如何通过 HtmlDocument.InvokeScript 将对象作为参数传递给 javascript

如何将 C# 对象作为参数传递给 Javascript 函数

如何将指针作为参数传递给 COM 对象中的函数?

如何将向量作为参数传递给另一个向量?

如何将类对象作为参数传递给不同的类方法?

如何将具有多个对象的状态数组作为参数传递给graphql突变?