Как я могу вызвать метод интерфейса, который требует IntPtr
параметр? Это работает очень хорошо, если мой метод требует string
, но не если это требует IntPtr
, Вот пример интерфейса в C #:
[
Guid("etc-etc-etc"),
InterfaceType(ComInterfaceType.InterfaceIsIDispatch),
ComVisible(true)
]
public interface ICallback
{
[DispId(1)]
void CallbackWithString( string value );
[DispId(2)]
void CallbackWithHandle( IntPtr value );
}
Я извлекаю класс COM в 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 );
Под «не работает» я имею в виду, что функция не вызывается, но исключение не возникает.
Можно ли отправить IntPtr
через COM взаимодействие? Если так, то как?
Ну, это не VT_HANDLE, это взлом от OleCtl.h. Версия CLR для SSCLI20 имеет свой вариант кода маршалинга в файле clr / src / vm / olevariant.cpp. Он преобразует VT_INT в IntPtr. Однако это 32-битный тип, я думаю, вам понадобится VT_I8, если он должен работать в 64-битном коде.
Других решений пока нет …