2009-07-01 14 views
21

私はgccで使用するcライブラリを持っています。ライブラリには拡張子.libがありますが、常に静的ライブラリとしてリンクされています。ライブラリをCコードとして使用するプログラムを書くと、すべてがokです。しかし、ファイルの名前を.cpp(c/C++の両方で動作する単純なものを行う)に変更すると、私は定義されていない参照を取得します。これらは、私がテスト目的のために書いた単純な小さなプログラムなので、すばらしいものはありません。私は以下を使用してコンパイルします:gcc/g ++を使用したCライブラリのリンクなし

gcc -g -Wall -I <path to custom headers> -o program main.c customlibrary.lib -lm -lpthread 

上記は魅力的です。しかし:

g++ -g -Wall -I <path to custom headers> -o program main.cpp customlibrary.lib -lm -lpthread 

又は

gcc -g -Wall -I <path to custom headers> -o program main.cpp customlibrary.lib -lm -lpthread -lstdc++ 

customlibrary.libの任意の関数に未定義の参照をもたらします。私はcustomlibrary.aというシンボリックリンクを作成しようとしましたが、運はありません。

g ++で私のライブラリが認識されないのはなぜですか?残念ながら私はライブラリのソースコードにアクセスすることはできませんが、c-libをC++にリンクすることは問題ではありませんか?

答えて

37

あなたのライブラリには、C++ではなくCから呼び出されることを前提としたAPIがあるようです。 C++では、ライブラリからエクスポートされたシンボルに関数名だけでなく、より多くの情報が含まれている必要があるため、これは重要です。これは、関数の名前を変更することによって処理されます。

あなたのライブラリには、パブリックインターフェイスを宣言するインクルードファイルがあると仮定します。 CとC++の両方と互換性を持たせるには、C++のコンパイラに、Cのリンケージと命名を使用すると宣言されている関数を宣言するように指示する必要があります。

これをテストする可能性が高い簡単な答えは、これを行うことです。あなたのmain.cppにだけではなく、直接customlibrary.hを含むで

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

#ifdef __cplusplus 
extern "C" { 
#endif 

と底部付近に、次の

自体は両方の言語で作業し、正しくC++とC-など、その機能を宣言するヘッダを作成するには、ヘッダファイルの先頭付近で次のように置きます。

#ifdef __cplusplus 
} 
#endif 
+1

2つのアンダースコアを有する__cplusplus'シンボル ':

// myfile.cpp extern "C" int libfun(); // C function in your library 

または全ヘッダファイルのためにそれを行います。このラウンド通常の方法は、特定の機能がCリンケージ必要コンパイラを伝えることです関連する基準によって。 – RBerteig

2

あなたのヘッダファイルは、Liを与えること

#ifdef __cplusplus 
extern "C" { 
#endif 

// ... 

#ifdef __cplusplus 
} /* extern "C" */ 
#endif 

通常のを持っていますbraryは明示的にCリンケージを機能させます。

.cppファイルは、デフォルトでC++リンケージ、つまりネームマングリングでコンパイルされます。

4

C++コンパイラは、名前マングリングとして知られていることを実行します。コードに表示される名前は、リンカが見るものと同じではありません。定義されるように、

// myfile.cpp 
extern "C" { 
    #include "mylibdefs.h"  // defs for your C library functions 
} 
関連する問題