OPC异步读与同步读的区别

一直用C++操作opc搞工控十多年了,从来都是同步读写,因为时效性并不要求过高,所以秉承“够用就行”的原则。其次也是因为同步读对异常处理比较方便。近来研究异步读写时,发现读取的数值与同步读取数值完全不一样,似乎顺序是乱的。

待认真研究代码后才发现,同步和异步的读取还是有本质区别的,不仅仅是异步回调的区别。

同步读取函数:

        virtual HRESULT STDMETHODCALLTYPE Read( 
            /* [in] */ OPCDATASOURCE dwSource,
            /* [in] */ DWORD dwCount,
            /* [size_is][in] */ OPCHANDLE *phServer,
            /* [size_is][size_is][out] */ OPCITEMSTATE **ppItemValues,
            /* [size_is][size_is][out] */ HRESULT **ppErrors) = 0;

ppItemValues(实时值)数组的顺序就是引入变量时的顺序。

而异步读取回调函数:

STDMETHODIMP  COPCDataCallback::OnReadComplete(
                /* [in] */ DWORD dwTransid,
                /* [in] */ OPCHANDLE hGroup,
                /* [in] */ HRESULT hrMasterquality,
                /* [in] */ HRESULT hrMastererror,
                /* [in] */ DWORD dwCount,
                /* [size_is][in] */ OPCHANDLE __RPC_FAR *phClientItems,   //异步读的Items顺序与同步不一样,重新调整了
                /* [size_is][in] */ VARIANT __RPC_FAR *pvValues,
                /* [size_is][in] */ WORD __RPC_FAR *pwQualities,
                /* [size_is][in] */ FILETIME __RPC_FAR *pftTimeStamps,
                /* [size_is][in] */ HRESULT __RPC_FAR *pErrors)

pvValues(实时值)数组的顺序并不是引入时的变量顺序,其顺序对应的是变量顺序数组phClientItems。

因此需要做一个顺序转换才能一一对应:

    if (pErrors[0] == S_OK)
    {
        DWORD i;
        for (i = 0;  i < dwCount; i++)
        {
            int x= phClientItems[i]-1;       //变量顺序号
            readValue[x] = pvValues[i].uiVal ;
            readQulity[x] = GetQualityText(pwQualities[i]);

            char pstrDateTime[32]={0};
            FileTimeToLocalSystemTime(pftTimeStamps[i], pstrDateTime);
            readTS[x] = pstrDateTime;
        }
    }

 

你可能感兴趣的:(bcb,OPC,C++)