現在、C#でExcelアドインを開発しており、C++ライブラリとの相互運用を使用しています。どちらも私が開発したものです。C ++ライブラリはCOMコンポーネントではなく、いくつかの関数をエクスポートするDLLにすぎません。
1つのC#関数があり、C ++関数に数値と2つの文字列を渡したいのですが、C++関数は文字列を返します。最初に文字列を直接返そうとしたので、プロトタイプは次のようになります
//C#
[return: MarshalAs(UnmanagedType.LPStr)]
private static extern string Function([MarshalAs(UnmanagedType.I4)] int number,
[MarshalAs(UnmanagedType.LPStr)]string str1,
[MarshalAs(UnmanagedType.LPStr)] string str2);
//C++
extern "C" __declspec(dllexport) string Function(int, char*, char*);
(ところで、私はすでにこの関数のC#の呼び出し規約をCdeclとして設定しています)
次に、C#バージョンを呼び出し、(デバッグ時に)C ++にステップインすると、パラメーターがシフトされていることがわかりました。したがって、整数は最初の文字列へのポインターの値であり、最初の文字列は2番目の文字列です。 2番目の文字列は別の場所を指しています。また、メモリを確認したところ、_cdecl規則に従ってパラメーターが渡されなかったことがわかりました。整数は、スタックにプッシュされた最後の整数でした(これは問題ありません)が、2つの文字列の位置が入れ替わっていました。コンパイラーが追加した情報は他にもたくさんあるので、これ以上深く掘り下げたくはありません。
ただし、後で戻り文字列をパラメーターとして変更すると、プロトタイプは次のようになります。
//C#
private static extern void Function([MarshalAs(UnmanagedType.I4)]int number,
[MarshalAs(UnmanagedType.LPStr)] string str1,
[MarshalAs(UnmanagedType.LPStr)] string str2,
[MarshalAs(UnmanagedType.LPStr), Out] StringBuilder returnStr);
//C++
extern "C" __declspec(dllexport) void Function(int, char*, char*, string&);
そして今、パラメータは正しく渡されます。
だから私の最初の質問は、これはどのように起こるのですか?
2番目の質問は、2番目のメソッドを使用しても、プログラムを正しく実行できず、C ++関数から戻るときにプログラムがクラッシュしたことです(実際にはC ++関数では、クラスの別のメンバー関数を呼び出すだけです。したがって、この関数はメンバー関数のラッパーのようであり、メンバー関数に戻るときにプログラムが正確にクラッシュしました。ワーパー関数はメンバー関数を呼び出すだけなので、問題がどこにあるのかわかりません)。
誰かがこれを行う方法を知っていますか?したがって、この関数の主なポイントは、数値と2つの文字列を取得し、別の文字列を返すことです。
よろしくお願いします。