powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Как установить связь с COM сервером и обрабатывать события?
15 сообщений из 15, страница 1 из 1
Как установить связь с COM сервером и обрабатывать события?
    #33666291
Фотография wolverin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В ОРС сервере (COM-сервер) реализован интерфейс IOPCDataCallback с уведомлением клиента о событиях через этот интерфейс, как реализовать обработку событий этого интерфейса на клиенте???
Описывал так
Код: plaintext
1.
2.
3.
4.
5.
STDMETHOD(OnDataChange)( DWORD dwTransid, OPCHANDLE hGroup,
HRESULT hrMasterquality, HRESULT hrMastererror,
DWORD dwCount, OPCHANDLE *phClientItems,
VARIANT *pvValues, WORD *pwQualities,
FILETIME *pftTimeStamps, HRESULT *pErrors);
Реализацию написал так
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
STDMETHODIMP OnDataChange( DWORD dwTransid, OPCHANDLE hGroup,
HRESULT hrMasterquality, HRESULT hrMastererror,
DWORD dwCount, OPCHANDLE *phClientItems,
VARIANT *pvValues, WORD *pwQualities,
FILETIME *pftTimeStamps, HRESULT *pErrors)
{
  return S_OK;
};

Я так понимаю нужно IConnectionPointContainer как-то использовать. Может сцылка у кого есть по этому поводу???
...
Рейтинг: 0 / 0
Как установить связь с COM сервером и обрабатывать события?
    #33666296
Фотография wolverin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Забыл
OnDataChange - один из методов интерфейса.
...
Рейтинг: 0 / 0
Как установить связь с COM сервером и обрабатывать события?
    #33666356
Фотография wolverin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В спецификации по OPC серверу написано

The notification mechanism is activated using the IconnectionPoint
technology:
1) Get a pointer on the server IConnectionPointContainer interface (through
the group ptr),
Делаю так
Код: plaintext
h = pItDescret->QueryInterface(&pConnect);
2)Get a pointer on the server IOPCDataCallback connection point interface;
we use the FindConnectionPoint method instead of the usual
QueryInterface,
Получаю
Код: plaintext
h = pConnect->FindConnectionPoint(IID_IOPCDataCallback, (IConnectionPoint**)&pDC);
А вот с этим чего делать не знаю
3)In order to give it to the server, get a pointer on the Callback interface of
this OPC client,
4) Give the client callback pointer to the server connection point and activate
the notification mechanism using the Advise method of the
IOPCDataCallback ConnectionPoint interface.
...
Рейтинг: 0 / 0
Как установить связь с COM сервером и обрабатывать события?
    #33666444
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
http://www.compdoc.ru/prog/cpp/com/ch7/ch76.shtml
______________________________________________
Вы имеете право хранить молчание! Всё что Вы скажете может быть использовано против Вас в суде!
...
Рейтинг: 0 / 0
Как установить связь с COM сервером и обрабатывать события?
    #33666777
Фотография wolverin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Petro123
Спасибо, но чего-то не получается:
1)
Код: plaintext
1.
2.
3.
4.
h = pItDescret->QueryInterface(&pConnect);
р = pConnect->FindConnectionPoint(IID_IOPCDataCallback, (IConnectionPoint**)&pDC);
DWORD dwCookie;
р = (IConnectionPoint*)pDC->Advise( СЮДА КАКОЙ УКАЗАТЕЛЬ ПИСАТЬ ,&dwCookie);
2) В статье

При программировании на Visual Basic можно объявить переменные, понимающие тип интерфейса обратного вызова

А на VC++ 7 как???
...
Рейтинг: 0 / 0
Как установить связь с COM сервером и обрабатывать события?
    #33667051
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
передаёшь указатель на себя, чтобы Там привели твой интерфейс к нужному m_pConsumer (думаю в документации к источнику события) и вызвали тебя

Код: plaintext
1.
    // извещаем потребителя о выполнении
    hr = m_pConsumer->OnProductIsDone();

______________________________________________
Вы имеете право хранить молчание! Всё что Вы скажете может быть использовано против Вас в суде!
...
Рейтинг: 0 / 0
Как установить связь с COM сервером и обрабатывать события?
    #33667063
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
,&dwCookie - твой адрес внутри сервера-издателя если "тебя подписали"
______________________________________________
Вы имеете право хранить молчание! Всё что Вы скажете может быть использовано против Вас в суде!
...
Рейтинг: 0 / 0
Как установить связь с COM сервером и обрабатывать события?
    #33667822
Фотография wolverin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Petro123передаёшь указатель на себя
Спасибо, только с этим-то я разобрался, но на что этот указатель должен ссылаться??? И мне не нужно вызывать, мне нужно подписаться и обработать этот вызов.
...
Рейтинг: 0 / 0
Как установить связь с COM сервером и обрабатывать события?
    #33667827
Фотография wolverin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Проще говоря, я не могу понять что от меня хотя в этих строках

3) In order to give it to the server, get a pointer on the Callback interface of
this OPC client
...
Рейтинг: 0 / 0
Как установить связь с COM сервером и обрабатывать события?
    #33667946
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Какое имя (GUID) интерфейса у тебя должен поддерживать клиент (и методы) я не знаю.
IMHO вряд ли здесь есть стандарты, т.к. события и параметры могут быть у каждого сервера какие угодно.

Удачи!

А у него нет библиотеки tlb с комментариями (может там и найдёшь описалово)?
______________________________________________
Вы имеете право хранить молчание! Всё что Вы скажете может быть использовано против Вас в суде!
...
Рейтинг: 0 / 0
Как установить связь с COM сервером и обрабатывать события?
    #33668031
Фотография wolverin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
tlb нету.
Вот описание интерфейса
Код: plaintext
1.
2.
3.
4.
#ifndef __IOPCDataCallback_FWD_DEFINED__
#define __IOPCDataCallback_FWD_DEFINED__
typedef interface IOPCDataCallback IOPCDataCallback;
#endif 	/* __IOPCDataCallback_FWD_DEFINED__ */
и конкретного метода
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
#ifndef __IOPCDataCallback_INTERFACE_DEFINED__
#define __IOPCDataCallback_INTERFACE_DEFINED__

/* interface IOPCDataCallback */
/* [unique][uuid][object] */ 


EXTERN_C const IID IID_IOPCDataCallback;

#if defined(__cplusplus) && !defined(CINTERFACE)
    
    MIDL_INTERFACE("39c13a70-011e-11d0-9675-0020afd8adb3")
    IOPCDataCallback : public IUnknown
    {
    public:
        virtual HRESULT STDMETHODCALLTYPE OnDataChange( 
            /* [in] */ DWORD dwTransid,
            /* [in] */ OPCHANDLE hGroup,
            /* [in] */ HRESULT hrMasterquality,
            /* [in] */ HRESULT hrMastererror,
            /* [in] */ DWORD dwCount,
            /* [size_is][in] */ OPCHANDLE *phClientItems,
            /* [size_is][in] */ VARIANT *pvValues,
            /* [size_is][in] */ WORD *pwQualities,
            /* [size_is][in] */ FILETIME *pftTimeStamps,
            /* [size_is][in] */ HRESULT *pErrors) =  0 ;
        
        
    };
    
#else 	/* C style interface */

    typedef struct IOPCDataCallbackVtbl
    {
        BEGIN_INTERFACE
        
        HRESULT ( STDMETHODCALLTYPE *OnDataChange )( 
            IOPCDataCallback * This,
            /* [in] */ DWORD dwTransid,
            /* [in] */ OPCHANDLE hGroup,
            /* [in] */ HRESULT hrMasterquality,
            /* [in] */ HRESULT hrMastererror,
            /* [in] */ DWORD dwCount,
            /* [size_is][in] */ OPCHANDLE *phClientItems,
            /* [size_is][in] */ VARIANT *pvValues,
            /* [size_is][in] */ WORD *pwQualities,
            /* [size_is][in] */ FILETIME *pftTimeStamps,
            /* [size_is][in] */ HRESULT *pErrors);
                                
        END_INTERFACE
    } IOPCDataCallbackVtbl;

    interface IOPCDataCallback
    {
        CONST_VTBL struct IOPCDataCallbackVtbl *lpVtbl;
    };
  

#ifdef COBJMACROS


#define IOPCDataCallback_OnDataChange(This,dwTransid,hGroup,hrMasterquality,hrMastererror,dwCount,phClientItems,pvValues,pwQualities,pftTimeStamps,pErrors)	\
    (This)->lpVtbl -> OnDataChange(This,dwTransid,hGroup,hrMasterquality,hrMastererror,dwCount,phClientItems,pvValues,pwQualities,pftTimeStamps,pErrors)

#endif /* COBJMACROS */


#endif 	/* C style interface */



HRESULT STDMETHODCALLTYPE IOPCDataCallback_OnDataChange_Proxy( 
    IOPCDataCallback * This,
    /* [in] */ DWORD dwTransid,
    /* [in] */ OPCHANDLE hGroup,
    /* [in] */ HRESULT hrMasterquality,
    /* [in] */ HRESULT hrMastererror,
    /* [in] */ DWORD dwCount,
    /* [size_is][in] */ OPCHANDLE *phClientItems,
    /* [size_is][in] */ VARIANT *pvValues,
    /* [size_is][in] */ WORD *pwQualities,
    /* [size_is][in] */ FILETIME *pftTimeStamps,
    /* [size_is][in] */ HRESULT *pErrors);


void __RPC_STUB IOPCDataCallback_OnDataChange_Stub(
    IRpcStubBuffer *This,
    IRpcChannelBuffer *_pRpcChannelBuffer,
    PRPC_MESSAGE _pRpcMessage,
    DWORD *_pdwStubPhase);

#endif 	/* __IOPCDataCallback_INTERFACE_DEFINED__ */
И GUID тоже есть.
На клиенте я знаю как описать (1 топик обработчик), а вот как подключить его что-то не соображу, хотя вроде все по алгоритму выполняю...
Может еще один
h = pItDescret->QueryInterface(IID_IOPCDataCallback, (IOPCDataCallback**)&pNew);
и его отправлять, только как будет связано с процедурой...
...
Рейтинг: 0 / 0
Как установить связь с COM сервером и обрабатывать события?
    #33668079
Фотография wolverin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А может надо реализовать свой интерфейс, по типу
Код: plaintext
1.
2.
3.
interface IProgrammer : IUnknown {
  :   :   :
  HRESULT Unadvise([in] DWORD dwCookie);
}
и уже указатель на него передавать???
...
Рейтинг: 0 / 0
Как установить связь с COM сервером и обрабатывать события?
    #33668179
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
я С++ мало знаю, но на Delphi :)
Код: plaintext
1.
QueryInterface(IOPCDataCallback - Интерфейс_свой, переменная); 
.....Advise(переменная, &dwCookie);

тебе придёт вызов OnDataChange(.......

тока ты её хотя бы пустую пропиши на клиенте.

Вроде так.
______________________________________________
Вы имеете право хранить молчание! Всё что Вы скажете может быть использовано против Вас в суде!
...
Рейтинг: 0 / 0
Как установить связь с COM сервером и обрабатывать события?
    #33668196
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
если перед QueryInterface в Delphi ничего не пишется, то значит мы берём указатель на интерфейс от "самого себя" (Self).

Какую ошибку то пишет?

Удачи!
______________________________________________
Вы имеете право хранить молчание! Всё что Вы скажете может быть использовано против Вас в суде!
...
Рейтинг: 0 / 0
Как установить связь с COM сервером и обрабатывать события?
    #33668315
Фотография wolverin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Petro123Какую ошибку то пишет?
Короче, от долгого копания в инете наткнулся на это
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
class Callback : public IOPCDataCallback 
{ 
public: 

   Callback() 
   { 
      m_ulRefs =  1 ; 
   } 
    
   //========================================================================== 
    // IUnknown 

   // QueryInterface 
   STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppInterface) 
   { 
      if (ppInterface == NULL) 
      { 
         return E_INVALIDARG; 
      } 

      if (iid == IID_IUnknown) 
      { 
         *ppInterface = dynamic_cast<IUnknown*>(this); 
         AddRef(); 
         return S_OK; 
      } 

      if (iid == IID_IOPCDataCallback) 
      { 
         *ppInterface = dynamic_cast<IOPCDataCallback*>(this); 
         AddRef(); 
         return S_OK; 
      } 

      return E_NOINTERFACE; 
   } 

   // AddRef 
   STDMETHODIMP_(ULONG) AddRef() 
   { 
        return InterlockedIncrement((LONG*)&m_ulRefs); 
   } 

   // Release 
   STDMETHODIMP_(ULONG) Release() 
   { 
        ULONG ulRefs = InterlockedDecrement((LONG*)&m_ulRefs); 

        if (ulRefs ==  0 ) 
        { 
            delete this; 
            return  0 ; 
        } 

        return ulRefs; 
   } 

   //========================================================================== 
    // IOPCDataCallback 

    // OnDataChange 
    STDMETHODIMP OnDataChange( 
        DWORD       dwTransid, 
        OPCHANDLE   hGroup, 
        HRESULT     hrMasterquality, 
        HRESULT     hrMastererror, 
        DWORD       dwCount, 
        OPCHANDLE * phClientItems, 
        VARIANT   * pvValues, 
        WORD      * pwQualities, 
        FILETIME  * pftTimeStamps, 
        HRESULT   * pErrors 
    ) 
   { 
      USES_CONVERSION; 

      for (DWORD ii =  0 ; ii < dwCount; ii++) 
      { 
         VARIANT vValue; 
         VariantInit(&vValue); 

         if (SUCCEEDED(VariantChangeType(&vValue, &(pvValues[ii]), NULL, VT_BSTR))) 
         { 
            _tprintf(_T("Handle = '%d', Value = '%s'\r\n"), phClientItems[ii], OLE2T(vValue.bstrVal)); 
            VariantClear(&vValue); 
         } 
      } 

      return S_OK; 
   } 

    // OnReadComplete 
    STDMETHODIMP OnReadComplete( 
        DWORD       dwTransid, 
        OPCHANDLE   hGroup, 
        HRESULT     hrMasterquality, 
        HRESULT     hrMastererror, 
        DWORD       dwCount, 
        OPCHANDLE * phClientItems, 
        VARIANT   * pvValues, 
        WORD      * pwQualities, 
        FILETIME  * pftTimeStamps, 
        HRESULT   * pErrors 
    ) 
   { 
      return S_OK; 
   } 

    // OnWriteComplete 
    STDMETHODIMP OnWriteComplete( 
        DWORD       dwTransid, 
        OPCHANDLE   hGroup, 
        HRESULT     hrMastererr, 
        DWORD       dwCount, 
        OPCHANDLE * pClienthandles, 
        HRESULT   * pErrors 
    ) 
   { 
      return S_OK; 
   } 


    // OnCancelComplete 
    STDMETHODIMP OnCancelComplete( 
        DWORD       dwTransid, 
        OPCHANDLE   hGroup 
    ) 
   { 
      return S_OK; 
   } 

private: 

   ULONG m_ulRefs; 
};

Испльзовал этот класс так
Код: plaintext
1.
2.
3.
4.
5.
h = pItDescret->QueryInterface(&pConnect);
h = pConnect->FindConnectionPoint(IID_IOPCDataCallback, (IConnectionPoint**)&pDC);
Callback* c = new Callback;
DWORD dwAdvise =  0 ;
h = ((IConnectionPoint*)pDC)->Advise(c,&dwAdvise);
Еще не проверял приходят ли сообщения, но ошибок в h не пишет, так что спасибо за участие, да еще спасибо за то, что вы меня как-то научили с DCOM в Delphi работать ;)
...
Рейтинг: 0 / 0
15 сообщений из 15, страница 1 из 1
Форумы / C++ [игнор отключен] [закрыт для гостей] / Как установить связь с COM сервером и обрабатывать события?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]