一.连接
使用到变量的说明 类型 说明 HRESULT 函数返回值,用来检测函数返回值(如:初始化COM库,查找CLSID,创建OPC服务等),提供函
数执行情况
CLSID 全球唯一标示符,用来确定OPC服务的标识,从注册表查找获得 LPWSTR LPSTR和LPWSTR是Win32和VC++所使用的一种字符串数据类型。LPSTR被定义成是一个指向
以NULL(‘\\0’)结尾的8位ANSI字符数组指针,而LPWSTR是一个指向以NULL结尾的16位双字节字符数组指针
OPC接口说明 IOPCServer *m_IOPCServer; IOPCServer 接口及成员函数主要用于对组对象进行创建,删除,枚 举和获取当前状态等操作.是
OPC 服务器对象的主要接口.接口及成员
IOPCItemMgt *m_IOPCItemMgt; IOPCItemMgt 接口及成员函数用于OPC 客户程序添加、删除
和组对象中组员等控制操作。
IOPCSyncIO *m_IOPCSyncIO; IOPCSyncIO 用于同步数据访问。
OPCITEMDEF m_Items[1]; OPCITEMDEF 数组,包含着项的存取路径, 定义和被请求的数据类
OPCITEMRESULT *m_ItemResult;
OPCITEMRESULT 数组,服务器用来告诉客户关于项的附加的信息(项句柄和规范的数据类型)
OPCHANDLE m_GrpSrvHandle; OPC服务的句柄,在多个函数中都会用到
使用到的函数说明
CoInitialize(NULL); 初始化COM库
CoInitialize是 Windows提供的API函数,用来告诉 Windows以单线程的方式创建com对象。应用程序调用com库函数(除CoGetMalloc和内存分配函数)之前必须初始化com库。
返回值S_OK : 该线程中COM库初始化成功S_FALSE 该线程中COM库已经被初始化 CoInitialize () 标明以单线程方式创建。
使用 CoInitialize 创建可以使对象直接与线程连接,得到最高的性能。
CoInitialize并不装载COM 库,它只用来初始化当前线程使用什么样的套间。使用这个函数后,线程就和一个套间建立了对应关系。线程的套间模式决定了该线程如何调用COM对象,是否需要列集等。 CoInitialize ()并不会干扰客户和服务器之间的通信,它所做的事情是让线程注册一个套间,而线程运行过程中必然在此套间。
CoInitialize和CoUninitialize必须成对使用
查找OPC服务
CLSIDFromProgID(L\"OPC服务的名称\ 通过ProgID,查找注册表中的相关CLSID 参数:1.服务的名称 2. CLSID型变量,用来接收注册表中查找到的CLSID
创建OPC服务器对象
CoCreateInstance (clsid, NULL, CLSCTX_LOCAL_SERVER ,IID_IOPCServer, (void**)&m_IOPCServer); 创建OPC服务器对象,并查询对象的IID_IOPCServer接口 参数:1. CLSID型变量,使用CLSIDFromProgID函数查找到的CLSID 2. 3.
函数功能描述:用指定的类标识符创建一个Com对象,用指定的类标识符创建一个未初始化的对象。当在本机中只创建一个对象时,可以调用CoCreateInstance;在远程系统中创建一个对象时,可以调用CoCreateInstanceEx;创建多个同一CLSID的对象时, 可以参考 CoGetClassObject 函数。 函数原形:
STDAPI CoCreateInstance(
REFCLSID rclsid, //创建的Com对象的类标识符(CLSID) LPUNKNOWN pUnkOuter, //指向接口IUnknown的指针 DWORD dwClsContext, //运行可执行代码的上下文 REFIID riid, //创建的Com对象的接口标识符
LPVOID * ppv //用来接收指向Com对象接口地址的指针变量 ); 参数: rclsid
[in] 用来唯一标识一个对象的CLSID(128位),需要用它来创建指定对象。 pUnkOuter
[in] 如果为NULL, 表明此对象不是聚合式对象一部分。如果不是NULL, 则指针指向一个聚合式对象的IUnknown接口。 dwClsContext
[in] 组件类别. 可使用CLSCTX枚举器中预定义的值. riid
[in] 引用接口标识符,用来与对象通信。 ppv
[out] 用来接收指向接口地址的指针变量。如果函数调用成功,*ppv包括请求的接口指针。 返回值: S_OK
指定的Com对象实例被成功创建。 REGDB_E_CLASSNOTREG
指定的类没有在注册表中注册. 也可能是指定的dwClsContext没有注册或注册表中的服务器类型损坏 CLASS_E_NOAGGREGATION 这个类不能创建为聚合型。 E_NOINTERFACE
指定的类没有实现请求的接口, 或者是IUnknown接口没有暴露请求的接口. 注释:
CoCreateInstance帮助者函数通过使用对象的CLSID,提供了一种便洁的方式与类对象连接,创建未初始化的实例,以及释放类对象。它封装了以下的功能:
CoGetClassObject(rclsid, dwClsContext, NULL, IID_IClassFactory, &pCF); hresult = pCF->CreateInstance(pUnkOuter, riid, ppvObj); pCF->Release();
当在本机中只创建一个对象时,调用CoCreateInstance是最方便的;如果要在远程系统中创建一个对象时,可以调用CoCreateInstanceEx;创建多个同一CLSID的对象时, 可以参考 CoGetClassObject 函数;如果创建多个对象实例,可以获得类对象的IClassFactory 接口指针,并使用需要的方法,可以使用CoGetClassObject函数。
在CLSCTX枚举器中, 你可以指定用来管理对象的服务器类型. 这些常量可以是
CLSCTX_INPROC_SERVER, CLSCTX_INPROC_HANDLER, CLSCTX_LOCAL_SERVER或是它们的任何组合. 常量CLSCTX_ALL被定义为这三个值的组合. 想获得更多的有关这些常量的用法,请参考CLSCTX.
添加组到OPC服务器
m_IOPCServer->AddGroup(L\"grp1\ // [in] 组名 TRUE, // [in] 活动状态 500, // [in] 向服务器发送请求的刷新率 1, // [in] 客户端的操作句柄 &TimeBias, // [in] 与标准时间的校正值 &PercentDeadband, // [in] 要舍弃的数据 LOCALE_ID, // [in] 服务器使用的语言 &m_GrpSrvHandle, // [out] 添加组以后服务器返回的组句柄 &RevisedUpdateRate, // [out] 服务器的数据刷新率 IID_IOPCItemMgt, // [in] 添加组的接口类型 (LPUNKNOWN*)&m_IOPCItemMgt); // [out] 服务器返回的接口对象指针
AddGroup函数的说明 HRESULT AddGroup( [in, string] LPCWSTR szName,
[in] BOOL bActive,
[in] DWORD dwRequestedUpdateRate, [in] OPCHANDLE hClientGroup, [unique, in] LONG *pTimeBias, [in] FLOAT * pPercentDeadband, [in] DWORD dwLCID,
[out] OPCHANDLE * phServerGroup, [out] DWORD *pRevisedUpdateRate, [in] REFIID riid,
[out, iid_is(riid)] LPUNKNOWN * ppUnk );
Parameters Description szName Name of the group. The name must be unique among the other groups created by this client. If no name is provided (szName is pointer to a NUL string) the server will generate a unique name. The server generated name will also be unique relative to any existing public groups. FALSE if the Group is to be created as inactive. TRUE if the Group is to be created as active. bActive dwRequestedUpdateRate Client Specifies the fastest rate at which data changes may be sent to OnDataChange for items in this group. This also indicates the desired accuracy of Cached Data. This is intended only to control the behavior of the interface. How the server deals with the update rate and how often it actually polls the hardware internally is an implementation detail. Passing 0 indicates the server should use the fastest practical rate. The rate is specified in milliseconds. hClientGroup Client provided handle for this group. [refer to description of data types, parameters, and structures for more information about this parameter] Pointer to Long containing the initial TimeBias (in minutes) for the Group. Pass a NULL Pointer if you wish the group to use the default system TimeBias. See discussion of TimeBias in General Properties Section See Comments below. The percent change in an item value that will cause a subscription callback for that value to a client. This parameter only applies to items in the group that have dwEUType of Analog. [See discussion of Percent Deadband in General Properties Section]. A NULL pointer is equivalent to 0.0. The language to be used by the server when returning values (including EU enumeration’s) as text for pTimeBias pPercentDeadband dwLCID operations on this group. This could also include such things as alarm or status conditions or digital contact states. phServerGroup Place to store the unique server generated handle to the newly created group. The client will use the server provided handle for many of the subsequent functions that the client requests the server to perform on the group. The server returns the value it will actually use for the UpdateRate which may differ from the RequestedUpdateRate. Note that this may also be slower than the rate at which the server is internally obtaining the data and updating the cache. In general the server should ‘round up’ the requested rate to the next available supported rate. The rate is specified in milliseconds. Server returns HRESULT of OPC_S_UNSUPPORTEDRATE when it returns a value in revisedUpdateRate that is different than RequestedUpdateRate. The type of interface desired (e.g. IID_IOPCItemMgt) Where to store the returned interface pointer. NULL is returned for any FAILED HRESULT. pRevisedUpdateRate riid ppUnk
添加项目
m_IOPCItemMgt->AddItems(1, // [in] 添加1个item m_Items, // [in] 添加的item的指针 &m_ItemResult, // [out] 添加item的结果 &m_pErrors); // [out] 发生的错误
m_Items的说明
定义:OPCITEMDEF m_Items[1];
这个参数为OPCITEMDEF结构,包含着项的存取路径, 定义和被请求的数据类等。
AddItems函数说明 HRESULT AddItems( [in] DWORD dwCount, [in, size_is(dwCount)] OPCITEMDEF * pItemArray, [out, size_is(,dwCount)] OPCITEMRESULT ** ppAddResults, [out, size_is(,dwCount)] HRESULT ** ppErrors );
Parameters dwCount pItemArray Description The number of items to be added Array of OPCITEMDEFs. These tell the server everything it needs to know about the item including the access path, definition and requested datatype ppAddResults Array of OPCITEMRESULTs. This tells the client additional information about the item including the server assigned item handle and the canonical datatype. Array of HRESULTs. This tells the client which of the items was successfully added. For any item which failed it provides a reason. ppErrors
OPCITEMDEF结构说明 typedef struct { [string] LPWSTR szAccessPath; [string] LPWSTR szItemID; BOOL bActive ; OPCHANDLE hClient; DWORD dwBlobSize; [size_is(dwBlobSize)] BYTE * pBlob; VARTYPE vtRequestedDataType; WORD wReserved; } OPCITEMDEF;
//OPC服务器存取路径 //item的名称 //活动状态 //操作句柄
//item的pBlob大小 //二进制指针
//数据类型由客户端请求 //保留字
Member szAccessPath Used by both Description The access path the server should associate with this item. By convention a pointer to a NUL string specifies that the server should select the access path. Support for accesspath is optional NOTE: version 1 indicated that a NULL pointer would allow the server to pick the path however passing a NULL pointer will cause a fault in the proxy/stub code and thus is not allowed. A null-terminated string that uniquely identifies the OPC data item. See the Item ID discussion and the AddItems function for specific information about the contents of this field. This Boolean value affects the behavior various methods as described elsewhere in this specification. The handle the client wishes to associate with the item. See the OPCHANDLE for more specific information about the contents of this field. The size of the pBlob for this item. pBlob is a pointer to the Blob. szItemID both bActive add hClient add dwBlobSize pBlob both both vtRequestedDataType both The data type requested by the client. An error is returned (See Additems or ValidateItems) if the server cannot provide the item in this format. Passing VT_EMPTY means the client will accept the servers canonical datatype.
查询同步接口
m_IOPCItemMgt->QueryInterface(IID_IOPCSyncIO, (void**)&m_IOPCSyncIO); 参数:1. IID_IOPCSyncIO 同步接口 2.服务器返回的用于操作同步接口的指针。 同步接口读取数据
m_IOPCSyncIO->Read(OPC_DS_DEVICE, 1, phServer, &pItemValue, &pErrors); 参数:
1.OPC_DS_DEVICE 从OPC设备读取 另一个选择是OPC_DS_CACHE从缓存读取 2.读取的数量
3.这个item的服务句柄
4.返回值的OPCITEMSTATE结构数值指针 5.返回的错误指针
HRESULT Read( [in] OPCDATASOURCE dwSource, [in] DWORD dwCount, [in, size_is(dwCount)] OPCHANDLE * phServer, [out, size_is(,dwCount)] OPCITEMSTATE ** ppItemValues, [out, size_is(,dwCount)] HRESULT ** ppErrors ); Parameters dwSource dwCount phServer ppItemValues ppErrors Description The ‘data source’; OPC_DS_DEVICE OPC_DS_CACHE or The number of items to be read. The list of server item handles for the items to be read Array of structures in which the item values are returned. Array of HRESULTs indicating the success of the individual item reads. The errors correspond to the handles passed in phServer. This indicates whether the read succeeded in obtaining a defined value, quality and timestamp. NOTE any FAILED error code indicates that the corresponding Value, Quality and Time stamp are UNDEFINED.
OPCITEMSTATE结构说明 typedef struct { OPCHANDLE hClient; FILETIME ftTimeStamp; WORD wQuality; WORD wReserved; VARIANT vDataValue; } OPCITEMSTATE; Member hClient Description the client provided handle for this item ftTimeStamp UTC TimeStamp for this item's value. If the device cannot provide a timestamp then the server should provide one. The quality of this item. The value itself as a variant. wQuality vDataValue
// 释放同步接口 m_IOPCSyncIO->Release(); m_IOPCSyncIO = NULL;
// 释放item管理接口 m_IOPCItemMgt->Release(); m_IOPCItemMgt = NULL;
// 释放 OPC服务器 m_IOPCServer->Release(); m_IOPCServer = NULL;
//关闭COM库 CoUninitialize();
异步OPC数据读取
查询group对象的异步接口
m_IOPCItemMgt->QueryInterface(IID_IOPCAsyncIO2, (void**)&m_IOPCAsyncIO2); 参数:1. IID_IOPCAsyncIO2 异步2.0接口 2.服务器返回的用于操作异步接口的指针。
获得IOPCGroupStateMgt接口
m_IOPCItemMgt->QueryInterface(IID_IOPCGroupStateMgt,(void**) &m_IOPCGroupStateMgt); 参数:1. IID_IOPCGroupStateMgt 组状态接口 2.服务器返回的用于操作接口的指针。
建立异步回调
CComObject 通过ATL模板创建回调对象的实例 CComObject 查询IUnknown接口 LPUNKNOWN pCbUnk; pCbUnk = pCOPCDataCallback->GetUnknown(); 建立一个服务器的连接点与客户程序接收器之间的连接 AtlAdvise 函数告诉一个可连接对象客户想从此可连接对象接收事件.该函数封装实现接收事件 HRESULT hRes = AtlAdvise( m_IOPCGroupStateMgt, // [in] 获得的IOPCGroupStateMgt接口指针 pCbUnk, // [in] IUnknown接口指针 IID_IOPCDataCallback, // [in]回调接口 &m_dwAdvise // [out] 服务器返回的回调接口的标识 ); 异步OPC数据释放 退出连接点时使用AtlUnadvise HRESULT hRes = AtlUnadvise(m_IOPCGroupStateMgt, IID_IOPCDataCallback, m_dwAdvise); m_IOPCGroupStateMgt->Release(); //异步的以下释放类似同步的OPC释放 m_IOPCItemMgt->RemoveItems( 1, // [in] 删除项目 phServer, // [in] 被删除项目的服务句柄 &pErrors // [out] 有错误时的指针 ); m_IOPCAsyncIO2->Release();//释放异步接口 m_IOPCAsyncIO2 = NULL; m_IOPCItemMgt->Release();//释放ITEM接口 m_IOPCItemMgt = NULL; m_IOPCServer->Release();//释放OPC服务 m_IOPCServer = NULL; CoUninitialize();//释放COM 用于客户端的异步回调定义 功能:客户提供用来操作组的数据变化和刷新 IOPCDataCallback IOPCDataCallback::OnDataChange HRESULT OnDataChange( [in] DWORD dwTransid, [in] OPCHANDLE hGroup, [in] HRESULT hrMasterquality, [in] HRESULT hrMastererror, [in] DWORD dwCount, [in, sizeis(dwCount)] OPCHANDLE * phClientItems, [in, sizeis(dwCount)] VARIANT * pvValues, [in, sizeis(dwCount)] WORD * pwQualities, [in, sizeis(dwCount)] FILETIME * pftTimeStamps, [in, sizeis(dwCount)] HRESULT *pErrors ); 参数描述 dwTransid 事务标识符,如果是一般的回调,此值为0。 hGroup 组的客户句柄。 hrMasterquality S_OK ,如果OPC_QUALITY_MASK 是OPC_QUALITY_GOOD,否则为 S_FALSE 。 hrMastererror 如果无错误,返回S_OK,否则返回S_FALSE.。 dwCount 读取的在客户句柄表里的项数目。 phClientItems 数据发生变化的项的客户句柄表。. pvValues 数据发生变化的项的VARIANTS 类型数据表。 pwQualities 读取的项的品质值的表。 pftTimeStamps 读取的项的时间戳表。 pErrors 项的HRESULTS 表。如果数据项的品质变为UNCERTAIN 或者 BAD,这里返回附加的 服务器提供的更有用的错误信息。 Parameters dwTransid Description 0 if the call is the result of an ordinary subscription. If the call is the result of a call to Refresh2 then this is the value passed to Refresh2. The Client handle of the group S_OK if OPC_QUALITY_MASK for all ‘qualities’ are OPC_QUALITY_GOOD, S_FALSE otherwise. S_OK if all ‘errors are S_OK, S_FALSE otherwise. The number of items in the client handle list hGroup hrMasterquality hrMastererror dwCount phClientItems pvValues The list of client handles for the items which have changed. A List of VARIANTS containing the values (in RequestedDataType) for the items which have changed. A List of Quality values for the items A list of TimeStamps for the items A list of HRESULTS for the items. If the quality of a data item has changed to UNCERTAIN or BAD., this field allows the server to return additional server specific errors which provide more useful information to the user. See below. pwQualities pftTimeStamps pErrors HRESULT 返回码 返回码描述 S_OK 客户总是返回S_OK。 ppErrors 返回码 返回码描述 S_OK 项的数据的品质是好的(OPC_QUALITY_GOOD)。 E_FAIL 项的操作失败。 OPC_E_BADRIGHTS 操作的项是不可读的。 OPC_E_UNKNOWNITEMID项在服务器的地址空间是不可用的。 S_xxx, E_xxx S_xxx – 卖方特殊信息。 E_xxx – 卖方指定的特殊错误。 对于所有的S_xxx 错误码,客户需要假设相应的值,品质和时间戳都 已经定义好了,不管品质是UNCERTAIN 或者BAD,建议服务器卖主提 供关于UNCRTAIN 或BAD 项的附加的信息。 回调发生在以下情况: 一个或者多个的数据变化事件。事件在活动Group 中的活动项的值或 者品质发生变化时发生。回调不会以超过刷新速率的速度发生。一般而 言,除非值或者品质发生变化,否则回调不会发生。transaction ID 为0。 通过AsyncIO2 接口的刷新请求。一旦请求发生,在活动Group 中的 活动项都会刷新。Transaction ID 不为0。 OPCDataCallback::OnReadComplete HRESULT OnReadComplete( [in] DWORD dwTransid, //事务标识符,如果是一般的回调,此值为0。 [in] OPCHANDLE hGroup, //组的客户句柄。 [in] HRESULT hrMasterquality, //S_OK ,如果OPC_QUALITY_MASK 是OPC_QUALITY_GOOD,否则 为 S_FALSE 。 [in] HRESULT hrMastererror, //如果无错误,返回S_OK,否则返回S_FALSE.。 Description This method is provided by the client to handle notifications from the OPC Group on completion of Async Reads. Parameters dwTransid hGroup hrMasterquality hrMastererror dwCount Description The TransactionID returned to the client when the Read was initiated. The Client handle of the group S_OK if OPC_QUALITY_MASK for all ‘qualities’ are OPC_QUALITY_GOOD, S_FALSE otherwise. S_OK if all ‘errors are S_OK, S_FALSE otherwise. The number of items in the client handle, values, qualities, times and errors lists. This may be less than the number of items passed to Read. Items for whic errors were detected and returned from Read are not included in the callback. The list of client handles for the items which were read. This is NOT guarenteed to be in any particular order although it will match the values, qualities, times and errors array. A List of VARIANTS containing the values (in RequestedDataType) for the items. A List of Quality values for the items A list of TimeStamps for the items A list of HRESULTS for the items. If the system is unable to return data for an item, this field allows the server to return additional server specific errors which provide more useful information to the user. [in] DWORD dwCount, //客户句柄里的项数目 [in, sizeis(dwCount)] OPCHANDLE * phClientItems, //项的客户句柄表 [in, sizeis(dwCount)] VARIANT * pvValues, //数据发生变化的项的VARIANTS 类型数据表。 [in, sizeis(dwCount)] WORD * pwQualities,// 读取的项的品质值的表。 [in, sizeis(dwCount)] FILETIME * pftTimeStamps,// 读取的项的时间戳表。 [in, sizeis(dwCount)] HRESULT *pErrors //项的HRESULTS 表。如果数据项的品质变为UNCERTAIN 或者 BAD, 这里返回附加的服务器提供的更有用的错误信息 ); phClientItems pvValues pwQualities pftTimeStamps pErrors IOPCDataCallback::OnWriteComplete HRESULT OnWriteComplete( [in] DWORD dwTransid, //事务标识符,如果是一般的回调,此值为0。 [in] OPCHANDLE hGroup, //组的客户句柄。 [in] HRESULT hrMasterError, //如果无错误,返回S_OK,否则返回S_FALSE。 [in] DWORD dwCount, //客户句柄表里的项数目 [in, sizeis(dwCount)] OPCHANDLE * phClientItems, //项的客户句柄表 [in, sizeis(dwCount)] HRESULT * pError ); //项的HRESULTS 表。如果数据项的品质变为UNCERTAIN 或者 BAD,这里返回附加的服务器提供的更有用的错误信息 Description This method is provided by the client to handle notifications from the OPC Group on completion of AsyncIO2 Writes. Parameters dwTransid hGroup hrMasterError dwCount Description The TransactionID returned to the client when the Write was initiated. The Client handle of the group S_OK if all ‘errors are S_OK, S_FALSE otherwise. The number of items in the client handle and errors list. This may be less than the number of items passed to Write. . Items for which errors were detected and returned from Write are not included in the callback. The list of client handles for the items which were written. This is NOT guarenteed to be in any particular order although it must match the ‘errors’ array. A List of HRESULTs for the items. Note that Servers are allowed to define vendor specific error codes here. These codes can be passed to GetErrorString(). phClientItems pErrors IOPCDataCallback::OnCancelComplete HRESULT OnCancelComplete( [in] DWORD dwTransid, //事务标识符,如果是一般的回调,此值为0。 [in] OPCHANDLE hGroup //组的客户句柄。 ); Description This method is provided by the client to handle notifications from the OPC Group on completion of Async Cancel. Parameters dwTransid hGroup Description The TransactionID provided by the client when the Read, Write or Refresh was initiated. The Client handle of the group 因篇幅问题不能全部显示,请点此查看更多更全内容