我正试图从c#中调用以下“foo”COM方法:
interface IFoo : public IUnknown
{
virtual HRESULT __stdcall foo( BSTR * log ) = 0;
}
以下是我在c#中声明的方式:
[ComImport, Guid( "98D93A58-2889-43a5-A182-47DEE781D41E" ),
InterfaceType( ComInterfaceType.InterfaceIsIUnknown )]
public interface IFoo
{
void foo( out string log );
}
以下是我在c#中调用它的方式: (x是实现IFoo的COM类的实例)
string log;
x.foo( out log );
当我运行此代码时,我得到以下异常:
System.Runtime.InteropServices.MarshalDirectiveException was unhandled
Message=Marshaler restriction: Excessively long string.
我做错了什么?
顺便说一句,如果我从c ++中调用“foo”,则以下内容正常工作:
CComBSTR log;
pX->foo( &log );
答案 0 :(得分:4)
您应该使用ref
说明符。请参阅Default Marshaling for Strings中的示例,尤其是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);
);