Сбой IOPCShutdown :: Сообщить: ошибка 80040202

#c #com #opc #dcom

#c #com #opc #dcom

Вопрос:

Я сломал голову, пока искал причину этой ошибки (4 дня)

  • У меня есть сервер OPC DA, работающий на удаленном компьютере.
  • Клиент OPC DA находится на другом компьютере.

в клиентской реализации я создаю внешний экземпляр через CoCreateInstanceEx()

 HRESULT result = ::CoCreateInstanceEx(clsid, NULL, clsctx, sinptr, 1, amp;mqi);
PRINT_COMERRORIF(result, "CoCreateInstanceEx failed");
 

и это работает нормально, и я получаю указатель на удаленный OPC-сервер ( mqi.pItf )

проблема возникает, когда я вызываю advise() функцию IConnectionPoint интерфейса

Я указываю, что нашел точку подключения, и я возвращаю указатель на интерфейс IOPCShutdown ( _MY_shutdown ) перед вызовом функции advise

 result = server_object->QueryInterface(IID_IConnectionPointContainer 
(void**)amp;connection_point_container);
PRINT_COMERRORIF(result, CTXID(this) "No IConnectionPointContainer interface");

result = connection_point_container->FindConnectionPoint(IID_IOPCShutdown, amp;_MY_shutdown);
PRINT_COMERRORIF(result, CTXID(this) "No IOPCShutdown connection point found");

result = _MY_shutdown->Advise(_MY_shutdown_callback, amp;_MY_shutdown_cookie); // HERE IS THE ISSUE 
PRINT_COMERRORIF(result, CTXID(this) "IOPCShutdown::Advise Failed");
 

и я получил эту ошибку:

 IOPCShutdown::Advise Failed : error 80040202
 

Я проверил настройку DCOM для обнаружения конфигурации удаленных OPC-серверов, и я сделал все, как описано, но никак; (

Вот моя конфигурация:

На стороне сервера

  - OPC DA Server installed and running

 - local user account is created

 - DCOM settings are configured as required

 - Policy settings are configured as well
 

На стороне клиента

  - OPC DA client interface installed.

 - local user accounts are created on the both Nodes. Accounts have the same 
   name and passwords like on the server.
 

брандмауэр отключен как на сервере, так и на клиенте.

Комментарии:

1. Ошибка 0x80040202 использует FACILITY_ITF, поэтому она специфична для этого IOPCShutdown::Advise. Вы должны спросить поставщика, что это значит. В противном случае, предположим, вы проверили, что ваш поток выполняется как STA или MTA. Многие серверы (особенно для событий) поддерживают один или другой (без явного документирования).

2. @SimonMourier чтобы увидеть потоки, мне нужно установить Process Monitor или similair, проблема в том, что у меня нет прав…

3. Ваш код выполняется в потоках, просто сбрасывает состояние потока, используя это, например: IComThreadingInfo::GetCurrentApartmentType

4. Неверный комментарий, это ошибка IConnectionPoint::Advice. Дает намек на основную проблему, для обратных вызовов все работает наоборот. Это должен быть вы, который реализует IOPCShutdown, сервер вызывает QueyInterface вашего интерфейса, чтобы получить указатель интерфейса IOPCShutdown. Если это не удается, то Advice() возвращает 0x80040202 (он же CONNECT_E_NOCONNECTION).

5. @HansPassant Я думаю ::FindConnectionPoint() , возвращает указатель на интерфейс IOPCShutdown, если это поддерживаемый исходящий интерфейс, и этот результат не дал сбоя. проблема заключается ::Advise() в попытке установить соединение между точкой подключения (последним указателем) и приемником клиента. Я не вижу источника этой проблемы

Ответ №1:

Правильно ли вы настроили параметры DCOM и политики на стороне клиента? Как упоминалось в комментариях, потому что для асинхронных подключений (когда вызывается обратный вызов) ваш клиент ведет себя как сервер, а сервер — как клиент.

Ответ №2:

Это работает, когда я меняю уровень аутентификации моего сервера OPC DA в конфигурации DCOM с «Connect» на «None», я не знаю почему, но это работает ^^