0

変更できない次のc++関数があります(サードパーティ):

[c++]

int __stdcall TEST(wchar_t **xml, int &result_size)
{
  // xml is instantiated here!
}

[c#]

class native
{
   [DllImport("somedll.dll")]

   public static extern int TEST(StringBuilder a, ref int size);
   {
   }
}

例:

 StringBuilder b = new StringBuilder();
 int size = 0;
 native.Test(b,ref size)

stringbuilder オブジェクトには最初の文字のみが含まれます。オブジェクトのサイズを変更すると:
b.Length = size; 最初の文字以外のデータが正しくありません。

これは wchar_t** を c++ から c# に渡す正しい方法ですか?

よろしく、

ジョン

4

1 に答える 1

3

関数は次のように p/invoked されます。

[DllImport(@"mylib.dll")]
static extern int TEST(out IntPtr xml);

null で終わる文字列を使用できるため、必要ないため、サイズ パラメータを削除しました。

次のように関数を呼び出します。

IntPtr xmlptr;
int retval = TEST(out xmlptr);
string xml = Marshal.PtrToStringUni(xmlptr);
// deallocate xmlptr somehow

注意が必要なのは、ネイティブ側に割り当てられたメモリの割り当てを解除することです。COM アロケータなどの共有アロケータを使用します。または、ネイティブ コードからデアロケーターをエクスポートします。

個人的には、COM BSTR を使用するようにインターフェイスを再設計します。C++ に BSTR を返させ、マネージ側で [MarshalAs(UnmanagedType.BStr)] を使用します。次に、フレームワークがすべての割り当て解除とマーシャリングを処理します。

于 2013-05-27T07:26:29.813 に答える