8

InterfaceLayer.soという動的ライブラリを作成しました。私が電話するとき:

> nm InterfaceLayer

出力として、次のようなシンボルが表示されます。

00000e28  T _Z5startv

コードで定義した関数の名前と同じように、 「 start 」であると期待していました。

なぜこれが起こるのですか?

4

3 に答える 3

15

これはC++の名前マングリングによるものです

nm -C

それらを解きほぐします。

名前のマングリングを防ぐために、

  • Cコンパイラ(g ++ではなくgcc)を使用し、ソースファイルに.c(.cppではなく)という名前を付けます。
  • またはextern"C"を宣言します:

my.h

  extern "C" 
  {
        void start();
        void finish();
  }

これにより、「C」リンケージが提供されます。つまり、オーバーロードしたり、参照で渡すことはできず、C++は何もできません:)

于 2011-05-17T19:30:39.130 に答える
3

C++の名前マングリングのように聞こえます。

于 2011-05-17T19:31:14.480 に答える
2

他の回答が述べているように、これはおそらくC++の名前マングリングによるものです。シンボルに「マングルされていない」名前でアクセスできるようにし、C ++で実装する場合はextern "C"、C++コンパイラにCリンケージがあることを通知する必要があります。

関数プロトタイプを含むヘッダーには、次のようなものが必要です。

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

// the prototype for start()...


#if defined(__cplusplus)
}
#endif

これにより、関数がC ++コンパイラで使用されてextern "C"いる場合は宣言が取得され、Cモジュールで使用されている場合は指定子によって混乱しないようになりextern "C"ます。

関数定義の前にヘッダーを含める場合、.cppファイルでの実装にはそのようなものは必要ありません。前の宣言で見たリンケージ仕様を使用します。ただし、すべてが同期していることを確認するためだけに、関数定義を装飾することを好みますextern "C"(.cppファイルでは、前処理を行う必要はありません#ifdef。常にC++としてコンパイルされます。

于 2011-05-17T19:34:27.490 に答える