C# 如何调用从c获取指向BSTR指针的COM方法#

C# 如何调用从c获取指向BSTR指针的COM方法#,c#,interop,marshalling,C#,Interop,Marshalling,我试图从c#调用以下“foo”COM方法: 下面是我如何用c#声明的: 下面是我在c#中的称呼: (x是实现IFoo的COM类的实例) 运行此代码时,会出现以下异常: System.Runtime.InteropServices.MarshalDirectiveException was unhandled Message=Marshaler restriction: Excessively long string. 我做错了什么 顺便说一下,如果我把C++的“FO”称为:,下面的工作就可

我试图从c#调用以下“foo”COM方法:

下面是我如何用c#声明的:

下面是我在c#中的称呼: (x是实现IFoo的COM类的实例)

运行此代码时,会出现以下异常:

System.Runtime.InteropServices.MarshalDirectiveException was unhandled
  Message=Marshaler restriction: Excessively long string.
我做错了什么

顺便说一下,如果我把C++的“FO”称为:

,下面的工作就可以正常工作了。
CComBSTR log;
pX->foo( &log );

您应该使用
ref
说明符。请参见中的示例,尤其是PassStringRef1和PassStringRef2

The following example shows strings declared in the IStringWorker interface.
Visual C++

public interface IStringWorker {
void PassString1(String s);
void PassString2([MarshalAs(UnmanagedType.BStr)]String s);
void PassString3([MarshalAs(UnmanagedType.LPStr)]String s);
void PassString4([MarshalAs(UnmanagedType.LPWStr)]String s);
void PassStringRef1(ref String s);
void PassStringRef2([MarshalAs(UnmanagedType.BStr)]ref String s);
void PassStringRef3([MarshalAs(UnmanagedType.LPStr)]ref String s);
void PassStringRef4([MarshalAs(UnmanagedType.LPWStr)]ref String s);
);

The following example shows the corresponding interface described in a type library.

[…]
interface IStringWorker : IDispatch {
HRESULT PassString1([in] BSTR s);
HRESULT PassString2([in] BSTR s);
HRESULT PassString3([in] LPStr s);
HRESULT PassString4([in] LPWStr s);
HRESULT PassStringRef1([in, out] BSTR *s);
HRESULT PassStringRef2([in, out] BSTR *s);
HRESULT PassStringRef3([in, out] LPStr *s);
HRESULT PassStringRef4([in, out] LPWStr *s);
);

我认为您不需要C端的out说明符。您可以控制
IFoo
?如果您可以将BSTR*更改为LPSTR*,则可以使用
StringBuilder
而不是
String
——这就是解决此错误的原因。我尝试了PassStringRef2示例。这仍然会导致相同的异常:字符串过长。
System.Runtime.InteropServices.MarshalDirectiveException was unhandled
  Message=Marshaler restriction: Excessively long string.
CComBSTR log;
pX->foo( &log );
The following example shows strings declared in the IStringWorker interface.
Visual C++

public interface IStringWorker {
void PassString1(String s);
void PassString2([MarshalAs(UnmanagedType.BStr)]String s);
void PassString3([MarshalAs(UnmanagedType.LPStr)]String s);
void PassString4([MarshalAs(UnmanagedType.LPWStr)]String s);
void PassStringRef1(ref String s);
void PassStringRef2([MarshalAs(UnmanagedType.BStr)]ref String s);
void PassStringRef3([MarshalAs(UnmanagedType.LPStr)]ref String s);
void PassStringRef4([MarshalAs(UnmanagedType.LPWStr)]ref String s);
);

The following example shows the corresponding interface described in a type library.

[…]
interface IStringWorker : IDispatch {
HRESULT PassString1([in] BSTR s);
HRESULT PassString2([in] BSTR s);
HRESULT PassString3([in] LPStr s);
HRESULT PassString4([in] LPWStr s);
HRESULT PassStringRef1([in, out] BSTR *s);
HRESULT PassStringRef2([in, out] BSTR *s);
HRESULT PassStringRef3([in, out] LPStr *s);
HRESULT PassStringRef4([in, out] LPWStr *s);
);