2016-12-09 4 views
-1

2つの.cppファイル(foo.cppとbar.cpp)をコンパイルし、共有オブジェクト(project.so)を作成しようとしています。しかし、コンパイルは失敗し、(の一部)私は取得していますエラーは次のとおりです。オブジェクトファイルの重複シンボル:

.... 
duplicate symbol _n in: 
foo.o 
bar.o 
ld: 5 duplicate symbols for architecture x86_64 
clang: error: linker command failed with exit code 1(use -v to see 
invocation) 
make: *** [project.so] Error 1 
ERROR: compilation failed for package ‘project’ 

私の.cppファイルにはいくつかの一般的なおよび珍しいヘッダファイルを、持っている一般的と稀という名前の関数の数、および一般的に命名のセット変数:

foo.cpp

#include <iostream> 
#include <fstream> 
#include <vector> 
#include <ctime> 
#include <cmath> 

size_t m1; 
double k1=2.0; 
std::vector<double> x,y; 
std::vector<double> z; 
size_t n,p; 

void inputfoo(){...} 
void output(){...} 

bar.cpp

#include <iostream> 
#include <fstream> 
#include <vector> 
#include <ctime> 
#include <cmath> 
#include "Eigen/Dense" 
#include "Eigen/Cholesky" 

size_t m2; 
double k2=2.0; 
std::vector<double> x,y; 
std::vector<double> z; 
size_t n,p; 

void inputbar(){...} 
void output(){...} 

私の試み:

私はそれぞれの.cppファイル内のグローバル変数の名前を異なる場合は、 '重複したシンボルのエラーの少ない数を取得することができています。私はfoo.cppでsize_t m1size_t m2 bar.cpp内にsize_t mを変更する場合には、ですが、私はエラーでこの部分を得ることはありません

duplicate symbol _m in: 
    foo.o 
    bar.o 

だから、今私が見ることができるのエラーで5つのシンボルx、y、z、n、p(それぞれの.cppファイルでグローバルに定義されています)

一般的な名前の関数の名前が異なる場合も同じです。以前、私はまた、誤って入力(に私を指示し

duplicate symbol __Z4inputP4init3RNGPi in: 
    foo.o 
    bar.o 

){...}関数をこの部分になるだろう。

したがって、一般的な名前の関数(input(){..})の名前をinputfooinputbarに変更し、それぞれのエラーが消えました。

ここで、各ファイルで名前を一意にすると、これらの2つを正常にコンパイルできます。しかし、x、y、z、n、pを変更することはできません。なぜなら、これらのファイルでは数多くあり、共通の名前付き関数と変数を持つ多くのファイルがあります。

誰でも私に説明してください。何が起こっているのか、それを修正する方法はありますか?私は本当にこれを引き起こしていることを知りたいです。私は前の記事「Understanding the origin of a linker duplicate symbol error」から読むことを試みましたが、それはヘッダ関連の問題ではないと思います。

ありがとうございました。

+0

名前空間を追加してみませんか? – flu

+0

@flu NSファイルに名前空間(またはNS)を追加することを意味しますか?私の理解は、それぞれの関数のNSがコンパイルが成功した後に追加されるということです。これはここでは起こりません。 NSが他の方法で追加できるかどうか、あるいは私がここで何かを見逃しているかどうかを知りたいのですか? – Usernow

+0

私はこのような名前空間をfoo.cppに追加することを意味しました:namespace foo {size_t m; ...}とbar.cpp:名前空間バー{size_t m; ...}。コメントに書かれた申し訳ありませんが、読みにくいです。 – flu

答えて

3

この例は不完全なため、コメントするのが難しいです。

しかし、両方のファイルにグローバルがあり、両方に表示されています。それは設計上の誤りです。あなたはどちらか

  • は、それらの状態が共有されていない場合は、各ファイルには、ローカル作り、それらを1つのファイルだけを宣言し、他でexternを使用して共有させること
  • ためstaticを使用することができます。

しかし、あなたが引用誤差が異なっており、我々はまた、あなたのinput::init() ...

について何も知らない、私もここにRcppに関連し、何も見えないので、WHTはそれのためのタグを追加しますか?

+0

'static'が私のトリックでした。私は今日これを学びました。ありがとうございました。あなたの答えを受け入れる。 P.S.もっと精巧な例を書いてはいけません。しかし、次回からもっとうまくいくでしょう。そして、Rcppが追加されたのは、エラーの原因を知らなかったからです。私が提供する情報が多いほど良いと思っていました。 – Usernow

関連する問題