4

C++ 共有ライブラリとの GCC リンクを見たことがありますが、それを自分で再現することはできません。最初に、テスト関数を含む C++ ライブラリを作成します。

g++ -shared -o libtest.so test.c

次に、ライブラリ関数を呼び出してこのようにコンパイルするテスト main 関数があります。

gcc -o prog.out main.c -L. -ltest

それから私はエラーを受け取ります

undefined reference to 'testfunc'

これは、ライブラリ内の異なる参照が原因だと思います... Cは関数testfuncに名前を付け、C++は関数に名前を付けます[いくつかのもの] __ testfunc [おそらくまたいくつかのもの]。

私も使ってみました

gcc -o prog.out main.c -l:libtest.so

しかし、これは同じエラーになります。

したがって、私の質問は次のとおりです。c++ライブラリをgccでacファイルにリンクするにはどうすればよいですか?

更新: を使用できることはわかっていますextern "C"が、それは解決方法ではありません。代わりに、リンカーのパラメーターがいくつかあるのではないでしょうか?

Update2: 最初の部分が c++ でコンパイルされ、gcc でリンクされている可能性も考えられます。これも試しました:

g++ -c testlib.c -o testlib.o
gcc -shared -o libtest.so testlib.o
gcc -o prog.out -l:libtest.so

まだ機能しません。フラグに何か問題がありますか?

4

3 に答える 3

8

はい、問題は共有ライブラリ (私は思う...) とは何の関係もなく、すべて名前マングリングに関係しています。

ヘッダーで、次のように関数を宣言する必要があります。

#ifdef __cplusplus
extern "C" {
#endif

void testfunc(void);

#ifdef __cplusplus
}
#endif

これによりtestfunc、C と C++ の両方で同じシンボルと呼び出し規約が使用されます。

私が現在使用しているシステムでは、C シンボル名は に_testfuncなり、C++ シンボル名 ( を使用しないextern "C"と仮定) は になります__Z8testfuncv。これにより、パラメーターの型に関する情報がエンコードされるため、オーバーロードが正しく機能します。たとえば、と衝突しないにvoid testfunc(int x)なります。__Z8testfunci__Z8testfuncv

于 2012-06-25T06:42:02.610 に答える
0

名前のマングリングが原因ではないと確信している場合。.so次に、ファイルが標準の場所にない限り、gccがライブラリを見つけられず、ライブラリのフルパスを指定しようとしたことを意味します。よくわからない場合は、変数(関数)名に競合がないか再確認してください。名前空間を使用してクラスをグループ化し、クラス内の関数を定義して、名前の競合を回避します

于 2012-06-25T10:34:52.573 に答える