0

3 つのソース ファイルがあります。メイン ファイルには、ifステートメントを使用してポインターを定義する関数があります。

main(int dispersalfn) {

if(dispersalfn == 0) {
    kernel1 = flatdisp;
  } else if(dispersalfn == 1) {
    kernel1 = expdisp;
  }

 [...more stuff...]

}

main.hは、次の定義がありますkernel1

arma::vec (*kernel1)(arma::vec d, arma::vec m);

にはdisp.cppと の定義がflapdispありexpdispます:

arma::vec flatdisp(arma::vec d, arma::vec m) {
  return m;
}

arma::vec expdisp(arma::vec d, arma::vec m) {
  return (square(m) / (2*M_PI)) % exp(-m % d);
}

disp.hと に対応する定義がflatdispありexpdispます。

arma::vec flatdisp(arma::vec d, arma::vec m);
arma::vec expdisp(arma::vec d, arma::vec m);

最後upfun.cppに、 を呼び出す関数がいくつかありますkernel1。の関数はupfun によって呼び出されmain()ます。

コンパイルすると、エラーが発生します。

 duplicate symbol _kernel in upfun.o and main.o for architecture x86_64

私のすべてのヘッダーファイルのソースは互いにインクルードガードを持っているので、それだけではないと思います。を呼び出すときにmain()、どの関数を に使用するかを選択する変数を含めますkernel1。これは、関数を別のファイルに分割するまで機能しました。このエラーの原因は何ですか?

4

1 に答える 1

3

あなたが言うつもりだったと仮定します:

duplicate symbol _kernel1 in upfun.o and main.o for architecture x86_64

リンカーは、シンボル (別名変数) "kernel1" が複数の場所で定義されていると不平を言っています。

問題は、ヘッダー ファイル main.h で変数「kernel1」を定義したことです。このヘッダー ファイルは、複数の .cpp ファイルに含まれています。したがって、複数のコンパイル単位で「kernel1」を効果的に定義しました。

解決策は簡単です。代わりに、「kernel1」の定義を main.cppに移動します。

arma::vec (*kernel1)(arma::vec d, arma::vec m);

アドレス コメントに追加された更新:

シンボル「kernel1」が別のファイルからも使用されていることが指摘されました。その場合、

  1. 「kernel1」の定義は、上記のように main.cpp で行う必要があります。

  2. main.h ヘッダー ファイルに kernel1 の「extern」宣言を追加します。

    extern arma::vec (*kernel1)(arma::vec d, arma::vec m);
    

これで問題が解決するはずです。

于 2013-10-02T00:14:47.273 に答える