在 C# 中将 ref IntPtr 编组到 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# 进行这样的调用?
I am trying to call a function which allocates memory for the string and then does something with the string. Here is the basic example which illustrates the problem:
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;
}
The following call from C++ program works just fine:
BSTR leftString = SysAllocString(L"Left String");
BSTR rightString = SysAllocString(L"Right String");
BSTR conString;
hr = pFunctionsCollection->Function2 ( leftString, rightString, & conString);
C# declaration:
Int32 Function2([In, MarshalAs(UnmanagedType.BStr)] String leftString,
[In, MarshalAs(UnmanagedType.BStr)] String rightString,
[In, Out] ref IntPtr conStr);
C# call:
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);
}
The program fails with
Call to Function2 failed with Insufficient memory to continue the execution of the program.
Does anyone knows how to make such a calls from C#?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
conString 是一个 BSTR,并且必须如此对待。请参阅 http://msdn.microsoft.com/en-us/library/ms221069。 aspx
C# 中的最后一个参数应该是编组为 BSTR 的输出字符串
[In, Out, MarshalAs(UnmanagedType.BStr)] out string conStr
您需要使用 SysAllocString 或 SysAllocStringLen 为 conStr 分配内存
List item
不能使用 'new 分配内存'并将其转换为 BSTR。 BSTR 对内存管理和布局有您无法满足的特定要求。您必须始终遵守这些约定。互操作失败,因为它期望您遵循 BSTR 约定,但您没有遵循。
conString is a BSTR, and must be treated as such. See http://msdn.microsoft.com/en-us/library/ms221069.aspx
You last parameter in C# should be an out string marshalled as a BSTR
[In, Out, MarshalAs(UnmanagedType.BStr)] out string conStr
You need to allocate the memory for conStr with SysAllocString or SysAllocStringLen
List item
You cannot allocate memory using 'new' and cast it to a BSTR. BSTR's have specific requirements for memory management and layout that you are not satisfying. You must follow these conventions always. The interop fails because it expects you are following the conventions for BSTRs, but you are not.