23

gccで使用するcライブラリがあります。ライブラリの拡張子は .lib ですが、常に静的ライブラリとしてリンクされています。ライブラリをCコードとして使用するプログラムを作成すると、すべてがOKになります。ただし、ファイルの名前を .cpp に変更すると (c/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++ find が私のライブラリを認識しないのはなぜですか。残念ながら、ライブラリのソース コードにアクセスすることはできませんが、c-lib を c++ にリンクすることは問題ではありませんか?

4

3 に答える 3

40

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

あなたのライブラリには、そのパブリック インターフェイスを宣言するインクルード ファイルがあると思います。C と C++ の両方と互換性を持たせるには、宣言する関数が C のリンケージとネーミングを使用すると想定する必要があることを C++ コンパイラに伝えるように手配する必要があります。

これをテストするためのおそらく簡単な答えは、これを行うことです:

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

直接含めるのではなく、main.cpp に入れますcustomlibrary.h

ヘッダー自体を両方の言語で機能させ、その関数を C に似たものとして C++ として正しく宣言するには、ヘッダー ファイルの先頭付近に次の行を追加します。

#ifdef __cplusplus
extern "C" {
#endif

そして、下部近くに次のとおりです。

#ifdef __cplusplus
}
#endif
于 2009-07-01T09:23:25.847 に答える
4

C++ コンパイラは、名前マングリングと呼ばれるものを実行します。コードに表示される名前は、リンカーが認識する名前とは異なります。これを回避する通常の方法は、特定の関数に C リンケージが必要であることをコンパイラーに伝えることです。

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

またはヘッダーファイル全体に対してそれを行います:

// myfile.cpp
extern "C" {
  #include "mylibdefs.h"      // defs for your C library functions
}
于 2009-07-01T09:23:59.980 に答える
2

あなたのヘッダーファイルは通常のものを持っていますか

#ifdef __cplusplus
extern "C" {
#endif

// ...

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

ライブラリ関数に C リンケージを明示的に与える。

.cpp ファイルは C++ リンケージ、つまりデフォルトで名前マングリングを使用してコンパイルされます。

于 2009-07-01T09:23:34.957 に答える