У меня есть COM-объект C++ (32 бит). Этот COM-объект вызывает COM-объект С# и как часть инициализации передает указатель интерфейса (IDispatch) на С#. Идея состоит в том, что код С# может перезвонить в COM-объект C++, используя этот интерфейс. Пример: C++ вызывает метод С# COM ->
OpenService(...., [..MarshalAs..IDispacth])
Проблема, с которой я сталкиваюсь, заключается в том, что когда С# пытается вызвать этот интерфейс, я получаю исключение MethodNotfound.
Внутри я объявляю интерфейс
[Comimport, Guid(...), Interfacetype.Dual]
public interface CallBackInterface
{
void SOData(int data)
}
Я передал данный указатель IDispatch этому интерфейсу
CallBackInterface cb = (CallbackInterface)inputObject;
cb.SoData(0);
Это тот вызов, который дает исключение NameNotfound в getIdsOfNames. Интересно, что я получил рефлектор и попытался отладить исходный код. Исключение похоже на ComEventsSinks.cs, но это не контейнер точки подключения или точка подключения. Я пытаюсь получить доступ к интерфейсу, данному вызывающим C++ объектом.
Я сдался и создал простой объект ATL COM, и я попытался сделать то же самое, и он отлично работает. Я мог даже до того, что мне в итоге захотелось сделать, CoMarshalInterfaceThreadInStream и CogetInterfaceandRelease поток из фонового потока, и все работает красиво.
Но по какой-то причине С# не может даже вернуться к C++ даже из исходного потока, не говоря уже о моем фоновом потоке.
Я почесываю голову из прошлых 2 или 3 дней и пробовал всевозможные вещи, но это бьет меня.
Есть идеи? указатели? Возможно, я делаю что-то глупое и глупое?
IDispatch предназначен для поздней привязки или "динамической" отправки. В этом случае, похоже, вы знаете форму интерфейса COM и уже имеете определение взаимодействия (CallBackInterface). Таким образом, вместо IDispatch вы должны иметь возможность использовать IUnknown и установить InterfaceType для InterfaceIsIUnknown.
Попробуйте это, и сообщите нам, если это сработает.
Если нет, и вам действительно нужно использовать IDispatch, то убедитесь, что ваш объект C++ правильно реализует IDispatch (вам понадобится библиотека типов и что-то вроде ATL IDispatchImpl).
Надеюсь, это поможет.
InterfaceIsDual
илиInterfaceIsIUnknown
, только сdynamic
или отражением.