2

それは私には簡単なことのように思えますが、それに対して反対する情報も賛成する情報も見つかりません。

デマングリングなどの観点からは、これは大きな問題ではないと思いますが、小さな小さな C++ ライブラリから関数を呼び出す小さな小さな C プログラムを作成する方法がわかりません。

私は現在Linuxを使用しており、静的バインディングを試しています。

これは、多くの人が直面していること、または多くの本で取り上げられていることに違いありませんが、私はこの問題の前に座っている盲目的な衝動のように感じます. 興味深いことに、SO についてもそのような質問はありません。

これが機能するかどうかさえわかりませんが、これを行う方法ははるかに少なくなります。

4

7 に答える 7

8

通常、エクスポートされた関数の C リンケージを使用してライブラリをビルドするように C++ コンパイラに強制する必要があります。

これを行うには、ヘッダーに次のことを行います。

#ifdef __cplusplus
extern "C" {
#endif

void func(void);

/* ... Other function defs go here ... */

#ifdef __cplusplus
}
#endif

通常、リンカは関数に対して C++ の名前マングリングを行うため、C リンカはそれらを見つけることができません。 extern "C"そうしないように強制します。C では有効ではない#ifdefため、 でラップする必要があります。extern "C"

アップデート

Charles Salvia が以下のコメントで述べているように、C には例外を処理する方法がない (少なくともプラットフォームに依存しない方法ではない) ため、例外がインターフェイスを通過しないようにする必要があります。

于 2010-10-25T13:15:33.103 に答える
4

C++ ライブラリが C インターフェイスを提供しない場合は、できません。

その場合は、C インターフェイスを使用してください。

あなたが作成者である場合は、このextern "C"機能を使用してください。http://www.parashift.com/c++-faq-lite/mixing-c-and-cpp.html

于 2010-10-25T13:15:17.850 に答える
3

個人的には、C リンケージを使用する関数をエクスポートする C++ ファイルを作成します。つまり、バインディングを記述します。

于 2010-10-25T13:27:28.787 に答える
2

Linux では、次のコマンドを使用して、C++ 関数の修飾名を取得できます。

nm my-tiny-c++lib.a

マングルされた名前で C から関数を呼び出しますが、このトリックが移植可能であるとは思わないでください...

編集: 次に、g++ を使用してリンクするか、gcc -lstdc++ を使用してリンクする必要があります

于 2010-10-25T13:49:46.180 に答える
2

デマングリングの観点からの問題です。Cから呼び出したい C++ の周りでextern Cを使用します。

マングリングとデマングリングは、プラットフォームに依存しすぎると見なされたため、C++ で標準化されることはありませんでした。その結果、リンカー出力を見て C++ メソッドのメソッド名を特定することはできますが、関数の C++ メソッドの「実際の」リンク可能な名前を見つける移植可能な方法はありません。

于 2010-10-25T13:15:10.993 に答える
1

C++ API を持つ任意の C++ ライブラリの周りに C ラッパーを作成できます。ラッパーは C++ で作成する必要があります。

C++ クラスを使用することもできます。それらを構造体として前方宣言します。これを行うと警告が表示されるコンパイラもありますが、おそらくこの警告を無効にするか、単に無視することができます。

そのような構造体 (完全な定義が表示されないため、インスタンスではありません) へのポインターを作成し、そのようなポインターとそのすべてのメソッドをパラメーターとして受け取ることによって破棄するために、自由関数を作成します。

クラスが名前空間にある場合、これを行うことはできないので、そのメンバーだけを持つ独自の構造体を作成し、代わりにその「ラッパー」を使用することに注意してください。

すべての C 関数に。ヘッダーのみに、

#ifdef __cplusplus
extern "C" {
#endif

// all your functions

#ifdef __cplusplus
}
#endif
于 2010-10-25T14:49:51.087 に答える
0

典型的なラッパーは次のようになります。

---- class_a.hpp ----

#include "class_a_wrapper"

class A {
     public:
     int foo(double p);
     double bar(int x, int y);
}

---- class_a_wrapper.h ----

#ifdef __cplusplus
extern "C" {
#endif

struct wrap_A;
int wrap_A_foo(struct wrap_A *obj, double p);
double wrap_A_bar(struct wrap_A *obj, int x, int y);

#ifdef __cplusplus
}
#endif

---- class_a_wrapper.cpp ----

#include "class_a.hpp"

int wrap_A_foo(struct wrap_A *obj, double p) {
    return (static_cast<A*>obj)->foo(p);
}
double wrap_A_bar(struct wrap_A *obj, int x, int y) {
    return (static_cast<A*>obj)->bar(x, y);
}
于 2010-10-26T13:52:19.843 に答える