2013-05-29 1 views
3

Как я могу вызвать метод интерфейса, для которого требуется параметр IntPtr? Это работает отлично, если мой метод требует string, но не требуется, если он требует. Вот пример интерфейса в C#:Передача IntPtr через COM-взаимодействие

[ 
    Guid("etc-etc-etc"), 
    InterfaceType(ComInterfaceType.InterfaceIsIDispatch), 
    ComVisible(true) 
] 
public interface ICallback 
{ 
    [DispId(1)] 
    void CallbackWithString(string value); 

    [DispId(2)] 
    void CallbackWithHandle(IntPtr value); 
} 

Я получаю СОМ-класс в C# из этого интерфейса, и передать его отправки в мой C++ приложений (через COM). Позже это приложение C++ вызывает мои методы в этой диспетчеризации для предоставления уведомлений обратно в приложение C#.

Это работает:

CComPtr<IDispatch> obj;  // My C# COM interop object, stored in my C++ app 
VARIANT arg; 

arg.vt = VT_BSTR; 
arg.bstrVal = myString; 
obj.InvokeN(L"CallbackWithString", &arg, 1); 

Это не работает:

arg.vt = VT_HANDLE;   // I also tried VT_BYREF, VT_VOID|VT_BYREF, and VT_INT_PTR 
arg.byref = myHandle; 
obj.InvokeN(L"CallbackWithHandle", &arg, 1); 

К "не работает", я имею в виду, что данная функция не вызывается, но не исключение.

Можно ли отправить через COM-взаимодействие? Если да, то как?

ответ

1

Ну, это не VT_HANDLE, это взлом от OleCtl.h. Версия CLR SSCLI20 имеет свой код маршалинга варианта в clr/src/vm/olevariant.cpp. Он преобразует VT_INT в IntPtr. Это, однако, 32-битный тип, я думаю, вам понадобится VT_I8, если это необходимо для работы в 64-битном коде.

+0

Спасибо Хансу. Он по-прежнему не работает, если мой параметр объявлен как 'IntPtr'. Мне пришлось изменить его на целое. Я пошел с 'UInt64', хотя я использую только 32-битный код. Я предпочел не делать этого и использовать 'IntPtr', но это похоже на рецепт разочарования. – paddy