QueryInterface терпит неудачу при приведении внутри реализации COM-интерфейса - PullRequest
0 голосов
/ 18 марта 2010

Я создаю инструмент в c # для извлечения сообщений из CAN-сети (сети в автомобиле) с использованием Dll, написанного на C / C ++. Эта dll может использоваться как COM-интерфейс.

Мой c # -formclass реализует один из этих COM-интерфейсов. И другие переменные создаются с использованием этих COM-интерфейсов (все работает отлично).

Проблема: интерфейс, который реализует моя C # -форма, имеет 3 абстрактных функции. Одна из этих функций называется -dll-, и мне нужно реализовать ее самостоятельно. В этой функции я хочу получить свойство переменной формы, которая имеет тип COM.

Библиотека COM - CANSUPPORTLib

Переменная всей формы:

private CANSUPPORTLib.ICanIOEx devices = new CANSUPPORTLib.CanIO();

Эта переменная также распространяется по форме и извлекается через переменную devices:

canreceiver = (CANSUPPORTLib.IDirectCAN2)devices.get_DirectDispatch(receiverLogicalChannel);

Функция, которая вызывается dll и реализуется в c #

    public void Message(double dTimeStamp)
    {
        Console.WriteLine("!!! message ontvangen !!!" + Environment.NewLine);

        try
        {
            CANSUPPORTLib.can_msg_tag message = new CANSUPPORTLib.can_msg_tag();
            message = (CANSUPPORTLib.can_msg_tag)System.Runtime.InteropServices.Marshal.PtrToStructure(canreceiver.RawMessage, message.GetType());
            for (int i = 0; i < message.data.Length; i++)
            {
                Console.WriteLine("byte " + i + ": " + message.data[i]);
            }
        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message);
        }
    }

Ошибка возникает в этой строке:

message = (CANSUPPORTLib.can_msg_tag)System.Runtime.InteropServices.Marshal.PtrToStructure(canreceiver.RawMessage, message.GetType());

Ошибка:

Unable to cast COM object of type 'System.__ComObject' to interface type CANSUPPORTLib.IDirectCAN2'. This operation failed because the QueryInterface call on the COM component for the interface with IID '{33373EFC-DB42-48C4-A719-3730B7F228B5}' failed due to the following error: No such interface supported (Exception from HRESULT: 0x80004002 (E_NOINTERFACE)).

Примечания: Можно иметь таймер, который каждые 100 мс проверяет наличие нужного мне сообщения. Затем сообщение получается точно так же, как и сейчас. Этот таймер запускается при запуске формы. Проверка выполняется только тогда, когда Message (double) установил для переменной значение true (пришло сообщение).

Когда таймер запускается в функции сообщения, у меня та же ошибка, что и выше

Запуск другого потока при запуске формы также невозможен.

Есть ли у кого-то опыт работы с COM-взаимодействием?

Когда этот таймер

1 Ответ

0 голосов
/ 19 марта 2010

Интересно, вызывается ли Message в потоке, отличном от того, который создал canreceiver.

Знаете ли вы модель потоков CANSUPPORTLib.CanIO? Если это многопоточный поток, вам может понадобиться направить ссылку из основного потока пользовательского интерфейса на поток, называемый Message каким-либо образом.

В качестве альтернативы, при условии, что вы можете изменить исходный код DLL C ++, и в зависимости от других требований и ограничений потоков вы можете изменить его на свободный поток, и в этом случае к объекту можно одновременно обращаться из нескольких потоков без сортировочная.

...