链接器 hell 中的 C++ 新手

标签 c++ g++ linker-errors

使用 g++ 并出现链接器错误。我有一个简单的程序,分为两个模块:main.cpp 和 Dice.h Dice.cpp。

主要.cpp:

#include <iostream>
#include "Dice.h"

int main(int argc, char **argv) {

    int dieRoll = Dice::roll(6);
    std::cout<<dieRoll<<std::endl;

    std::cin.get();

    return 0;
}

骰子.h:

#ifndef DieH
#define DieH

namespace Dice
{
    int roll(unsigned int dieSize);
}

#endif

骰子.cpp:

#include <ctime>
#include <cstdlib>
#include "Dice.h"

namespace Dice
{
    int roll(unsigned int dieSize)
    {
        if (dieSize == 0)
        {
            return 0;
        }
        srand((unsigned)time(0));
        int random_int = 0;
        random_int = rand()%dieSize+1;

        return random_int;
    }
}

我使用 g++ 编译和链接这些文件如下:

g++ -o program main.cpp Dice.cpp

我收到以下链接器错误:

Undefined symbols:
"Dice::roll(int)", referenced from:
  _main in ccYArhzP.o
ld: symbol(s) not found
collect2: ld returned 1 exit status

我完全糊涂了。任何帮助将不胜感激。

最佳答案

您的代码格式正确。

确保您的文件名没有冲突,文件存在并且包含您认为的内容。例如,您可能有一个空的 Dice.cpp,而您正在其他地方编辑一个新创建的文件。

通过删除不必要的文件来最小化可能的差异;只有main.cppdice.hdice.cpp

您的错误与您的代码不匹配:"Dice::roll(int)"。请注意,这是在寻找 int,但您的函数采用 unsigned int。确保您的 header 匹配。


尝试以下操作:

g++ main.cpp -c

这将生成 main.o,即已编译但未链接的 main 代码。对 dice.cpp 做同样的事情:

g++ dice.cpp -c

您现在有两个需要链接在一起的目标文件。这样做:

g++ main.o dice.o

然后看看是否可行。如果没有,请执行以下操作:

nm main.o dice.o

这将列出一个对象中所有可用的符号,并且应该给你这样的东西:

main.o:
00000000 b .bss
00000000 d .ctors
00000000 d .data
00000000 r .eh_frame
00000000 t .text
00000098 t __GLOBAL__I_main
00000069 t __Z41__static_initialization_and_destruction_0ii
         U __ZN4Dice4rollEj
         U __ZNSi3getEv
         U __ZNSolsEPFRSoS_E
         U __ZNSolsEi
         U __ZNSt8ios_base4InitC1Ev
         U __ZNSt8ios_base4InitD1Ev
         U __ZSt3cin
         U __ZSt4cout
         U __ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_
00000000 b __ZStL8__ioinit
         U ___gxx_personality_v0
         U ___main
00000055 t ___tcf_0
         U _atexit
00000000 T _main

dice.o:
00000000 b .bss
00000000 d .data
00000000 t .text
00000000 T __ZN4Dice4rollEj
         U _rand
         U _srand
         U _time

C++ 破坏了函数名,这就是为什么一切看起来都很奇怪的原因。 (注意,mangling names 没有标准方式,GCC 4.4 就是这样做的)。

观察 dice.omain.o 引用相同的符号:__ZN4Dice4rollEj。如果这些不匹配,那是你的问题。例如,如果我将 dice.cpp 的一部分更改为:

// Note, it is an int, not unsigned int
int roll(int dieSize)

然后 nm main.o dice.o 产生以下内容:

main.o:
00000000 b .bss
00000000 d .ctors
00000000 d .data
00000000 r .eh_frame
00000000 t .text
00000098 t __GLOBAL__I_main
00000069 t __Z41__static_initialization_and_destruction_0ii
         U __ZN4Dice4rollEj
         U __ZNSi3getEv
         U __ZNSolsEPFRSoS_E
         U __ZNSolsEi
         U __ZNSt8ios_base4InitC1Ev
         U __ZNSt8ios_base4InitD1Ev
         U __ZSt3cin
         U __ZSt4cout
         U __ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_
00000000 b __ZStL8__ioinit
         U ___gxx_personality_v0
         U ___main
00000055 t ___tcf_0
         U _atexit
00000000 T _main

dice.o:
00000000 b .bss
00000000 d .data
00000000 t .text
00000000 T __ZN4Dice4rollEi
         U _rand
         U _srand
         U _time

请注意,这给出了两个不同的符号。 main.o 寻找这个:__ZN4Dice4rollEj 和包含这个 __ZN4Dice4rollEidice.o。 (最后一个字母不同)。

当尝试编译这些不匹配的符号时(使用 g++ main.o dice.o),我得到:

undefined reference to `Dice::roll(unsigned int)'

关于链接器 hell 中的 C++ 新手,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1665269/

相关文章:

c++ - 如何减少 Qt 布局内小部件之间的差距

c++ - 为什么这个 type_traits 代码给我一个整数到指针转换警告?

没有默认构造函数的 C++ 继承

c++ - 无法链接 duma 库

c++ - 为什么在 C++ 中键入 void main() 是不好的

C++ continue 语句导致无限循环

linux - 警告 : Corrupted shared library list

c++ - 尝试从命令行使用 g++ 编译时获取 "Access is denied"。赛格温

c++ - MSVC 链接器错误 LNK2001 unresolved external for template method defined in cpp file

c++ - 了解维特比算法