【问题标题】:inline function linker error内联函数链接器错误
【发布时间】:2010-10-31 12:32:09
【问题描述】:

我正在尝试使用特定类的内联成员函数。例如没有内联的函数声明和实现是这样的:

在头文件中:

int GetTplLSize();

在 .cpp 文件中:

int NeedleUSsim::GetTplLSize()
{
    return sampleDim[1];
}

由于某种原因,如果我将“inline”关键字放在实现和声明中的任何一个以及两个地方,我都会得到链接器错误,如下所示:

创建库 C:\DOCUME~1\STANLEY\LOCALS~1\TEMP\MEX_HN~1\templib.x 和对象 C:\DOCUME~1\STANLEY\LOCALS~1\TEMP\MEX_HN~1\templib.exp mexfunction.obj:错误 LNK2019:函数 _mexFunction 中引用的未解析外部符号“public:int __thiscall NeedleUSsim::GetTplLSize(void)”(?GetTplLSize@NeedleUSsim@@QAEHXZ) mexfunction.mexw32:致命错误 LNK1120:1 未解决的外部 C:\PROGRA~1\MATLAB\R2008B\BIN\MEX.PL:错误:“mexfunction.mexw32”的链接失败。

为了摆脱这个错误需要做什么(即我在制作这些内联成员函数方面做错了什么)?

【问题讨论】:

    标签: c++ inline linker-errors


    【解决方案1】:

    然后您需要将函数定义放入标题中。提示编译器内联的最简单方法是在类声明中包含方法体,例如:

    
    class NeedleUSsim
    {
      // ...
      int GetTplLSize() const { return sampleDim[1]; }
      // ...
    };
    

    或者,如果您坚持单独声明和定义:

    
    class NeedleUSsim
    {
      // ...
      int GetTplLSize() const;
      // ...
    };
    
    inline int NeedleUSsim::GetTplLSize() const
    { return sampleDim[1]; }
    

    定义必须在使用该方法的每个翻译单元中可见。

    【讨论】:

    • 这是唯一的方法吗? (出于可读性原因,我想将声明和实现分开)
    • 基本上是的。编译器在编译对它的调用时必须知道函数的主体,因此主体必须在包含的头文件中。但是,您仍然可以只在类声明中声明该函数,然后在头文件的稍后位置添加实现。
    • 我明白了。我想那时我只需要忍受这种方式编写代码。感谢您的建议。
    • 有些人喜欢将内联函数放在一个单独的头文件中,并从主头文件中包含它(在末尾),而不是将它们放在主头中。我个人并不是 100% 相信它(这对我来说感觉像是在浪费时间),但如果你喜欢它,它是另一种选择。
    • 是的,我不想提那个 .inl 可怜的技术 :)
    【解决方案2】:

    来自 C++ FAQ Lite

    如果你把内联函数的 定义到 .cpp 文件中,如果它 从其他一些 .cpp 文件调用, 你会得到一个“未解决的外部” 链接器出错。

    How do you tell the compiler to make a member function inline?

    【讨论】:

    • 不幸的是,正如我刚刚发现的那样,在 MSVC 2013 和 2015 中并非如此。我在 CPP 文件(在库中)中有一个内联,它的代码是从一些完全不同的 CPP 源代码,它们有自己的同名内联代码(但代码略有不同,因此结果确实破坏了测试)。我认为这是该开发环境中的错误。很难找到...
    【解决方案3】:

    正如其他人已经指出的那样,您需要将内联函数的定义移动到头文件中,如下所示:

    class NeedleUSsim
    {
      // ...
      inline int GetTplLSize() { return sampleDim[1]; }
      // ...
    };
    

    这样做的原因是编译器在看到对内联函数的调用时需要知道要内联哪些代码。如果将函数的定义保留在 NeedleUSsim 类的 .cpp 文件中,编译器为其生成的代码将被困在 NeedleUSsim 目标文件中。由于编译器只读取源代码——它从不窥探另一个类的目标文件——它根本无法知道在编译另一个 .cpp 文件时用什么代码替换调用。

    【讨论】:

      【解决方案4】:

      如果你有一个内联函数,你应该把定义放在头文件中。

      【讨论】:

      • 我尝试将 inline 关键字放在头文件中的定义上,但仍然出现相同的链接器错误。
      • 不仅仅是 inline 关键字,整个定义应该放在头文件中。所以,把它从你的 .cpp 文件移到你的 .h 文件中。
      【解决方案5】:

      请参阅Inline Guard Macro idiom。这至少可以让您将代码与声明分开,尽管会稍微分开。它还允许您通过define 切换函数的内联。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-10-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-12
        • 2011-08-24
        • 1970-01-01
        相关资源
        最近更新 更多