在C#中编组引用IntPtr到BSTR *

时间:2010-11-10 08:54:40

标签: marshalling com-interop bstr

我正在尝试调用一个为字符串分配内存的函数,然后对字符串执行某些操作。以下是说明问题的基本示例:

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#进行此类调用?

1 个答案:

答案 0 :(得分:1)

conString是一个BSTR,必须这样对待。见http://msdn.microsoft.com/en-us/library/ms221069.aspx

  1. 您应该使用SysStringLen来获取BSTR的长度
  2. C#中的最后一个参数应该是作为BSTR编组的out字符串

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

  3. 您需要使用SysAllocString或SysAllocStringLen

  4. 为conStr分配内存
  5. 列出项目

  6. 您不能使用'new'分配内存并将其强制转换为BSTR。 BSTR对您不满意的内存管理和布局有特定要求。您必须始终遵循这些惯例。互操作失败是因为它希望您遵循BSTR的约定,但您不是。