2011-01-04 10 views
6

Cmockeryを使用して、C++コードから呼び出されたC関数を模擬したいと思っています。私はテストしています。その第一歩として、私はrun_tests.cppするCmockery例run_tests.cと改名しました、そしてコンパイルしcmockery.cとリンクしようとしています:C++コードをコンパイルしてCコードとリンクするにはどうすればよいですか?

g++ -m32 -DHAVE_CONFIG_H -DPIC -I ../cmockery-0.1.2 -I /usr/include/malloc -c run_tests.cpp -o obj/run_tests.o 
gcc -m32 -DHAVE_CONFIG_H -DPIC -Wno-format -I ../cmockery-0.1.2 -I /usr/include/malloc -c ../cmockery-0.1.2/cmockery.c -o obj/cmockery.o 
g++ -m32 -o run_tests obj/run_tests.o obj/cmockery.o 

最初の2本のコマンドラインは(コンパイルする)成功しています未定義のシンボルがrun_tests.cppのライン29からのものであることを

Undefined symbols: 
    "_run_tests(UnitTest const*, unsigned long)", referenced from: 
     _main in run_tests.o 
ld: symbol(s) not found 
collect2: ld returned 1 exit status 

return run_tests(tests); 

run_tests()関数はcmockerで定義されているが、私が得る最後の後y.c.

"Linking C++ code with 'gcc' (without g++)" を読んだ後、私が試した:

gcc -lstdc++ -m32 -o run_tests obj/run_tests.o obj/cmockery.o 

をしかし、同じ結果だ:それはCコードでシンボルを見つけたので、私は++コードをコンパイルおよびリンクCはどうすればよい

Undefined symbols: 
    "_run_tests(UnitTest const*, unsigned long)", referenced from: 
     _main in run_tests.o 
ld: symbol(s) not found 
collect2: ld returned 1 exit status 

を?あなたのC++コードが含まれ、あなたのヘッダファイルで

+0

私はcmockery.hを変更する必要がないことを明確にしています(このコメントを書いている時点で)。 run_tests.cppの '#include 'の周りに 'extern" C "宣言を置くことができます。私はこれを明確にする最初の答えを受け入れます。 –

答えて

7

は、私はあなたがcmockery.hファイルの内容を中心に、以下を追加することにより、C++からリンクするthinkgsを得ることができると思いますエンドは:

#if defined(__cplusplus) 
} 
#endif 

そのように、Cソースのヘッダーを使用することは、ビルド++宣言のextern "C"一部を無視するが、ヘッダがある場合、Cに含まれますコンパイラは、そのヘッダー内の宣言のリンケージがCのセマンティクスを使用していることを正しく伝えられます。クイックのn-汚いテストのために

か、むしろヘッダーを変更したくない場合、あなたは試すことができます:

extern "C" { 
#include "cmockery.h" 
} 

が、私の好みは、ヘッダにextern "C"ブロックを置くことであろう(とのみ必要なものの周りに - それは少しの分析が必要かもしれません)。

+0

なぜ、 'extern" C ""を '#include" "quick-n-dirty"の周りに置くことを検討しますか? –

+0

一般的には、 'extern" C修飾子を期待しないものに適用するかもしれません(特にヘッダにC++対応の他のヘッダが含まれている場合)。ヘッダーは 'extern" C++の宣言仕様を使ってこれを扱うことができましたが、このケースを処理するために一度しか使われていないことが分かりました。おそらくほとんど知られておらず、 'extern" C " 'バージョン)。 –

5

、あなたは、あなたがC++からのCヘッダファイルが含まれている場合C.

2

でコンパイルされているすべての関数のextern "C"宣言を必要とするあなたはextern "C" { .... }でプロトタイプを包んありますか?あなたがしない場合、C++の関数名はリンク時に 'mangled'になります。

2

カールが言ったように、extern "C" { .. }が必要です。

理由:C++はリンクがタイプセーフであるように名前を変えます(面白い文字を追加します)。 Cはそうではないので、foo(int)からfoo(double)にリンクする言語では(間違っていて恥ずかしい)。

正常に相互運用できるようにするには、リンクが成功するために、いくつかの関数名がマングルされないようにC++コンパイラに指示する必要があります。初め

またはその付近:

#if defined(__cplusplus) 
extern "C" { 
#endif 

またはその付近

関連する問題