Как вызвать метод COM, который берет указатель на BSTR из c # - PullRequest
2 голосов
/ 03 декабря 2011

Я пытаюсь вызвать следующий метод "foo" из c #:

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 является экземпляром класса COM, который реализует IFoo)

string log;
x.foo( out log );

Когда я запускаю этот код, я получаю следующее исключение:

System.Runtime.InteropServices.MarshalDirectiveException was unhandled
  Message=Marshaler restriction: Excessively long string.

Что я делаю не так?

Кстати, следующее работает правильно, если я вызываю "foo" из c ++ следующим образом:

CComBSTR log;
pX->foo( &log );

1 Ответ

4 голосов
/ 03 декабря 2011

Вы должны использовать спецификатор 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);
);
...