7

他の C++ コードで解決できるように、より単純な名前のプラグインが必要です。

class B {
};

extern "C" B foo(); // to avoid name mangling in order to be loaded by dlsym

そして、プログラムの他の部分 (これも C++ であり、クラス B の同じ定義をプラグインと共有しています):

B (*func)();
func = dlsym("/path/to/so", "foo");
B m = func();

そのようなコードは問題を引き起こしますか? つまり、(標準で) C++ クラスをextern "C"関数のパラメーターまたは戻り値の型として使用することは許可されていますか? 私の gcc では動作するようですが、他の gcc ではどうでしょうか?

4

3 に答える 3

2

いくつかの条件で、それはうまくいくはずです:

  • クラス B の定義を別のものに切り替えようとしても、うまくいきません。変更できるのは foo() の定義だけです。
  • プラグインとロード プログラムの両方が、バイナリ レベルでクラス B のインターフェイスに同意する必要があります。コンパイラ (バージョンといくつかのフラグを含む) を切り替えると、このインターフェイスが変更される可能性があります。
  • 当然、C++ では dlsym() の戻り値をキャストする必要があります。
  • C でクラスを使用することはできません。
于 2013-01-27T15:44:30.410 に答える
1

もちろん、 foo() を as として宣言extern "C"すると、実際のマングルされていない関数名を使用して dlsym() を介してロードできますが、それ以外の場合は、ロード後のその関数の使用方法には影響しません。

通常のルールは引き続き適用されます。foo() またはクラス B のいずれかのバイナリ互換性が失われた場合、プラグインを再コンパイルする必要があります。これは、通常の非ランタイム ロード ダイナミック ライブラリである場合にプラグインを再コンパイルする必要がある場合と同じです。

于 2013-01-27T16:05:46.147 に答える
0

C++ だけに固執し、C++ のみに固執している限り、これは機能します。明らかな理由により、関数宣言を C 翻訳単位でコンパイルすることはできません。(つまり、C コンパイラに何が何であるかを適切に説明することはできませんB。)

したがって、ここで目にする唯一の問題は、質問の [C] タグの意味です。C との何らかの相互互換性も必要ですか?

于 2013-01-27T19:19:16.317 に答える