使用 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.cpp
、dice.h
和dice.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.o
和 main.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
和包含这个 __ZN4Dice4rollEi
的 dice.o
。 (最后一个字母不同)。
当尝试编译这些不匹配的符号时(使用 g++ main.o dice.o
),我得到:
undefined reference to `Dice::roll(unsigned int)'
关于链接器 hell 中的 C++ 新手,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1665269/