foo.dll に次の C++ クラスがあるとします。
class a{
private:
int _answer;
public:
a(int answer) { _answer = answer; }
__declspec(dllexport) int GetAnswer() { return _answer; }
}
C# から pInvoke GetAnswer を使用したいと思います。そのために、次の方法を使用します。
[DllImport("foo.dll", CallingConvention = CallingConvention.ThisCall, EntryPoint= "something")]
public static extern int GetAnswer(IntPtr thisA);
そして、a を指す IntPtr を渡します (別の場所から取得したもので、重要ではありません)。 CallingConvention = CallingConvention.ThisCall
正しく処理されていることを確認します
この質問の素晴らしいところは、すでにうまく機能しているので、これまでのところ自分が正しいことを知っているということです! Depends.exe を使用すると、"GetAnswer" が ?GetAnswer@a@@UAEHXZ としてエクスポートされていることがわかります (またはそれに近いもの - ポイントは、名前がマングルされていることです)。マングルされた名前を EntryPoint の「何か」に差し込むと、すべてがうまく機能します! Depends.exe を使用できるようになるまでに約 1 日かかりました。そのため、同様の問題を抱えている人の助けとしてここに残しておきます。
私の本当の質問は次のとおり です。 GetAnswer で C++ の名前マングリングを無効にして、マングルされた名前をエントリ ポイントとして入力する必要がないようにする方法はありますか。名前のマングリングについての私の理解は、コンパイラが変更されると変更される可能性があるためです。また、pInvoke するすべてのインスタンス メソッドに Depends.exe を使用するのは面倒です。
編集:私が試したことを追加するのを忘れました:定義に貼り付けることができますが、関数宣言にextern "C"を置くことができないようです。ただし、これは役に立たないようです (考えてみれば明らかです)。
私が考えることができる他の唯一の解決策は、インスタンス メソッドをラップし、a のインスタンスをパラメーターとして受け取る c スタイルの関数です。次に、そのラッパーで名前マングリングを無効にし、それを pInvoke します。ただし、すでに持っているソリューションに固執したいと思います。私は同僚に pInvoke が素晴らしいことをすでに伝えました。pInvoke を機能させるためだけに C++ ライブラリに特別な関数を入れなければならないとしたら、私はばかみたいに見えるでしょう。