2

g++ を使用しており、リンカー エラーが発生しています。main.cpp と Dice.h Dice.cpp の 2 つのモジュールに分割された単純なプログラムがあります。

main.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;
}

Dice.h:

#ifndef DieH
#define DieH

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

#endif

Dice.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

私は完全に困惑しています。どんな助けでも大歓迎です。

4

3 に答える 3

9

あなたのコードは整形式です。

競合するファイル名がないことを確認してください。ファイルが存在し、ファイルの機能が含まれていることを確認してください。たとえば、Dice.cpp空の があり、新しく作成した を別の場所で編集しているとします。

不要なファイルを削除して、矛盾を最小限に抑えます。main.cpp、、dice.hおよびのみがありdice.cppます。

エラーがコードと一致しません: "Dice::roll(int)"。これは を探してintいますが、関数はunsigned int. ヘッダーが一致していることを確認してください。


次のことを試してください。

g++ main.cpp -c

これによりmain.o、メインのコンパイル済みでリンクされていないコードが生成されます。で同じことを行いdice.cppます:

g++ dice.cpp -c

これで、互いにリンクする必要がある 2 つのオブジェクト ファイルができました。次のようにします。

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++ は関数名を混乱させるため、すべてが奇妙に見えます。(名前をマングリングする標準的な方法はないことに注意してください。これは GCC 4.4 の方法です)。

それを観察し、同じ記号dice.oを参照してください: . これらが一致しない場合は、それが問題です。たとえば、の一部を次のように変更すると:main.o__ZN4Dice4rollEjdice.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

これは 2 つの異なる記号を与えることに注意してください。main.othis: を探し、 this__ZN4Dice4rollEjdice.o含みます__ZN4Dice4rollEi。(最後の文字が異なります)。

これらの不一致のシンボルを (を使用してg++ main.o dice.o) コンパイルしようとすると、次のようになります。

undefined reference to `Dice::roll(unsigned int)'
于 2009-11-03T04:42:33.267 に答える
1

あなたの問題は、あなたが呼び出しDice::roll(int)ていて、関数を書いたDice::roll(unsigned int)ことです。探している関数は実際には存在しません (内部的には、関数の引数の型はその名前と同じくらい重要です。これがオーバーロードのしくみです)。6uunsigned int (たとえば) を渡してみて、それが機能するかどうかを確認してください。または、ヘッダー ファイルが両方のファイルで一致しない可能性があり、main.cpp は関数が (符号付き) int を受け取ると見なします。

于 2009-11-03T04:39:15.113 に答える
0

そのようなことを聞​​きたくないのはわかっていますが、「それは私にとってうまくいきます!」.

あなたのエラーは疑わしいほど古いようです - どのバージョンの GCC を使用していますか? これは GCC 2.x のように見えます! また、main.cpp で dieRoll を unsigned として入力してみてください。これにより、この古いコンパイラの名前空間の問題が解決される可能性があります。

于 2009-11-03T04:41:55.093 に答える