如何转换C++;PBSTR到C#字符串 有一个C++ ActiveX OCX,带有以下ODL声明: DISP_FUNCTION(CHellerCommCtrl, "GetRecipePath", GetRecipePath, VT_I4, VTS_PBSTR) 需要调用C++程序中的GetRecipePath,将所得的C++ BSTR转换成C。 我从其他岗位了解到以下解决方案: string s1 = Marshal.PtrToStringAnsi((IntPtr)outPtr);

如何转换C++;PBSTR到C#字符串 有一个C++ ActiveX OCX,带有以下ODL声明: DISP_FUNCTION(CHellerCommCtrl, "GetRecipePath", GetRecipePath, VT_I4, VTS_PBSTR) 需要调用C++程序中的GetRecipePath,将所得的C++ BSTR转换成C。 我从其他岗位了解到以下解决方案: string s1 = Marshal.PtrToStringAnsi((IntPtr)outPtr);,c#,casting,com-interop,bstr,C#,Casting,Com Interop,Bstr,问题是,C#via interop中GetRecipePath的原型具有参数“ref string”,不允许我将结果“string”类型转换为“IntPtr”,然后将其传递给封送处理方法。 如何将从GetRecipePath[实际上是一个BSTR]获得的“字符串”转换为C#string?a不仅仅是一个指向unicode字符串的指针,它以长度为前缀,通过特定api分配和释放,并在传递到另一个方法时隐含所有权的更改 如果您的outPtr是BSTR,则您可以执行以下操作: string s1 = Ma

问题是,C#via interop中GetRecipePath的原型具有参数“ref string”,不允许我将结果“string”类型转换为“IntPtr”,然后将其传递给封送处理方法。 如何将从GetRecipePath[实际上是一个BSTR]获得的“字符串”转换为C#string?

a不仅仅是一个指向unicode字符串的指针,它以长度为前缀,通过特定api分配和释放,并在传递到另一个方法时隐含所有权的更改

如果您的
outPtr
是BSTR,则您可以执行以下操作:

string s1 = Marshal.PtrToStringBSTR(outPtr)
我不确定
Marshal.PtrToStringBSTR()
是否为您释放了BSTR(文档中没有明确说明这一点),但如果没有,您可以调用
Marshal.FreeBSTR(outPtr)

或者,您可以在托管COM接口中使用字符串,并使用
[marshallas(UnmanagedType.BStr)]
对其进行修饰。不幸的是,我不太熟悉
DISP_函数
IDispatch
,但我猜C中的方法签名是这样的:

[PreserveSig] 
int GetRecipePath([MarshalAs(UnmanagedType.BSTR)] out string path);
或者更好:

[return: MarshalAs(UnmanagedType.BSTR)]
string GetRecipePath();

C++字符串是用“0”结尾的字节[]。使用Encoding.UTF8.GetString(byte[])将其转换为字符串。我将尝试您的建议,但必须注意,BSTR是一个Unicode字符串,而不是[ASCII]字节字符串。我相信这就是马歇尔方法所做的,将Unicode转换成ASCII。不要把单词放在我嘴里。我从未使用过ASCII码。如果有两个字节字符,则使用Unicode编码而不是UTF8编码。Ascii删除不可打印的字符。尝试对OCX返回的字符串编码.Unicode.GetBytes以获取字节数组。然后在字节数组上应用Encoding.UTF8.GetString,得到我认为是UTF8字符串但却是双字节Unicode字符串。然后简单地不进行任何编码,而是直接使用从OCX返回的字符串,显然这已经是一个UTF8字符串。但是上面的ODL声明显然返回了PBSTR。OCX是否发送Unicode字符串?C#可以同时处理Unicode和UTF8字符串吗?事实上,C#可以直接处理Unicode字符串吗?谢谢。我从来没有完全理解一个字符串如何同时包含一个字节和两个字节的字符。我知道它可以但从来没有观察过字符是如何分开的。从方法名
GetRecipePath
判断,我猜VTS_PBSTR表示
[out,retval]
参数,即指针BSTR