0

文字列にメモリを割り当ててから、文字列で何かを行う関数を呼び出そうとしています。問題を説明する基本的な例を次に示します。

C++:

    STDMETHODIMP CFunctionsCollection::Function2 (  
        BSTR leftString, BSTR rightString, BSTR * conString
    )
{
    int leftLen = lstrlen(leftString);
    int rightLen = lstrlen(rightString);

    *conString = new TCHAR[leftLen+rightLen+1];

    for (int i=0 ; i<leftLen ; ++i)
        (*conString)[i] = leftString[i];
    for (int i=0 ; i<rightLen ; ++i)
        (*conString)[leftLen+i] = rightString[i];
    (*conString)[leftLen+rightLen] = 0;

    return S_OK;
}

C++ プログラムからの次の呼び出しは問題なく機能します。

BSTR leftString = SysAllocString(L"Left String");
BSTR rightString = SysAllocString(L"Right String");
BSTR conString;
hr = pFunctionsCollection->Function2 ( leftString, rightString, & conString);

C# 宣言:

Int32 Function2([In, MarshalAs(UnmanagedType.BStr)] String leftString,
                [In, MarshalAs(UnmanagedType.BStr)] String rightString,
                [In, Out] ref IntPtr conStr);

C# 呼び出し:

try
{
    String leftString = "Left String"; 
    String rightString = "Right String";
    IntPtr outStr = IntPtr.Zero;
    pFunctionsCollection.Function2(leftString, rightString, ref outStr);
    String outString = Marshal.PtrToStringUni(outStr);
    Console.WriteLine("Out String = {0}", outString);
}
catch (Exception e)
{
    Console.WriteLine("Call to Function2 failed with {0}", e.Message);
}

プログラムは失敗します

Function2 の呼び出しは、メモリ不足のためプログラムの実行を続行できませんでした。

C#からそのような呼び出しを行う方法を知っている人はいますか?

4

1 に答える 1

1

conString は BSTR であり、そのように扱う必要があります。http://msdn.microsoft.com/en-us/library/ms221069.aspxを参照してください。

  1. BSTR の長さを取得するには、SysStringLen を使用する必要があります。
  2. C# の最後のパラメーターは、BSTR としてマーシャリングされた出力文字列である必要があります

    [In, Out, MarshalAs(UnmanagedType.BStr)] out string conStr

  3. SysAllocString または SysAllocStringLen で conStr のメモリを割り当てる必要があります

  4. リスト項目

「new」を使用してメモリを割り当て、それを BSTR にキャストすることはできません。BSTR には、満たされていないメモリ管理とレイアウトに関する特定の要件があります。これらの規則には常に従う必要があります。BSTR の規則に従っていると想定されているが、そうでないため、相互運用は失敗します。

于 2011-04-01T00:46:24.717 に答える