OPC读写Kepware(C++)
OPC读写Kepware(C++opc同步读写)
”rw“ 是kepserver6.5的OPF文件,需要kepserver6.5及以上版本才能打开OPF文件,打开后如下图。
将各种接口封装成类…
OpcClient.h
#include "opcda.h"
#include "OpcError.h"
#include "iostream"
#include "opccomn.h"
#define LOCALE_ID 0x409
using namespace std;
class OpcClient
{
public:
OpcClient();
~OpcClient();
IOPCServer *m_IOPCServer;
IOPCItemMgt *m_IOPCItemMgt;
IOPCSyncIO *m_IOPCSyncIO;
OPCITEMDEF m_Items[1];
OPCITEMRESULT *m_ItemResult;
OPCHANDLE m_GrpSrvHandle;
HRESULT *m_pErrors;
bool OpcClientBusy;
int connectToServer(LPWSTR ProgID, LPWSTR GrpID);
int addItemtoGrp(LPWSTR szItemID, VARTYPE vt_ItemType);
int readShort(LPWSTR OPCServerProgID, LPWSTR groupID,LPWSTR szItemID, VARTYPE vt_ItemType);
int writeShort(LPWSTR OPCServerProgID, LPWSTR groupID, LPWSTR szItemID, int value);
float readFloat(LPWSTR OPCServerProgID, LPWSTR groupID, LPWSTR szItemID, VARTYPE vt_ItemType);
int writeFloat(LPWSTR OPCServerProgID, LPWSTR groupID, LPWSTR szItemID, float value);
bool readBool(LPWSTR OPCServerProgID, LPWSTR groupID, LPWSTR szItemID, VARTYPE vt_ItemType);
int writeBool(LPWSTR OPCServerProgID, LPWSTR groupID, LPWSTR szItemID, bool value);
int setBool(LPWSTR OPCServerProgID, LPWSTR groupID, LPWSTR szItemID, VARTYPE vt_ItemType);
int resetBool(LPWSTR OPCServerProgID, LPWSTR groupID, LPWSTR szItemID, VARTYPE vt_ItemType);
int invertBool(LPWSTR OPCServerProgID, LPWSTR groupID, LPWSTR szItemID, VARTYPE vt_ItemType);
int Stop();
private:
};
OpcClient.cpp
#include "stdafx.h"
#include "OpcClient.h"
int OpcClient::connectToServer(LPWSTR ProgID, LPWSTR GrpID)
{
OpcClientBusy = true;
HRESULT r1;
CLSID clsid;
LONG TimeBias = 0;
FLOAT PercentDeadband = 0.0;
DWORD RevisedUpdateRate;
//初始化COM库
m_ItemResult = NULL;
r1 = CoInitialize(NULL);
//通过ProgID,查找注册表中的机关CLSID
r1 = CLSIDFromProgID(ProgID, &clsid);
if (FAILED(r1))
{
CoUninitialize();
return 1;
}
//创建 OPC服务对象,并查询对象的IID_IOPCServer接口
r1 = CoCreateInstance(clsid, NULL,
CLSCTX_LOCAL_SERVER, IID_IOPCServer,
(void**)&m_IOPCServer);
if (r1 != S_OK)
{
m_IOPCServer = NULL;
CoUninitialize();
return 2;
}
//添加一个Group,并查询IOPCItemMgt接口
r1 = m_IOPCServer->AddGroup(GrpID,
TRUE,
500,
1,
&TimeBias,
&PercentDeadband,
LOCALE_ID,
&m_GrpSrvHandle,
&RevisedUpdateRate,
IID_IOPCItemMgt,
(LPUNKNOWN*)&m_IOPCItemMgt);
if (r1 == OPC_S_UNSUPPORTEDRATE)
{
return 3;
}
else if (FAILED(r1))
{
m_IOPCServer->Release();
m_IOPCServer = NULL;
CoUninitialize();
return 4;
}
return 0;
}
int OpcClient::addItemtoGrp(LPWSTR szItemID, VARTYPE vt_ItemType)
{
if (OpcClientBusy == false)
{
return 1;
}
HRESULT r1;
//为ADDItem定义item表的参数
m_Items[0].szAccessPath = L"";
m_Items[0].szItemID = szItemID;
m_Items[0].bActive = TRUE;
m_Items[0].hClient = 1;
m_Items[0].dwBlobSize = 0;
m_Items[0].pBlob = NULL;
m_Items[0].vtRequestedDataType = vt_ItemType;
r1 = m_IOPCItemMgt->AddItems(1,
m_Items,
&m_ItemResult,
&m_pErrors);
if (r1 == S_OK)
{
//cout << "ADDItems()成功!" << endl;
}
if ((r1 != S_OK) && (r1 != S_FALSE))
{
//cout << "ADDItems失败!!" << endl;
m_IOPCItemMgt->Release();
m_IOPCItemMgt = NULL;
m_GrpSrvHandle = NULL;
m_IOPCServer->Release();
m_IOPCServer = NULL;
CoUninitialize();
return 1;
}
//检测Itemr的可读可写性
if (m_ItemResult[0].dwAccessRights != (OPC_READABLE + OPC_WRITEABLE))
{
return 2;
}
else
{
//
}
//查询group对象的同步接口
r1 = m_IOPCItemMgt->QueryInterface(IID_IOPCSyncIO, (void**)&m_IOPCSyncIO);
if (r1<0)
{
CoTaskMemFree(m_ItemResult);
m_IOPCItemMgt->Release();
m_IOPCItemMgt = NULL;
m_GrpSrvHandle = NULL;
m_IOPCServer->Release();
m_IOPCServer = NULL;
CoUninitialize();
return 3;
}
return 0;
}
int OpcClient::readShort(LPWSTR OPCServerProgID, LPWSTR groupID, LPWSTR szItemID, VARTYPE vt_ItemType)
{
OpcClient::connectToServer(OPCServerProgID, groupID);
OpcClient::addItemtoGrp(szItemID, vt_ItemType);
OPCHANDLE *phServer;
OPCITEMSTATE *pItemValue;
HRESULT *pErrors;
HRESULT r1 = E_FAIL;
if (m_pErrors[0] != S_OK)
{
return 32767;
}
//内存分配
phServer = new OPCHANDLE[1];
phServer[0] = m_ItemResult[0].hServer;
r1 = m_IOPCSyncIO->Read(OPC_DS_DEVICE, 1, phServer, &pItemValue, &pErrors);
//释放内存
delete[]phServer;
if (r1 == S_OK)
{
//
}
else
{
Stop();
return 32767;
}
Stop();
return pItemValue[0].vDataValue.intVal;
}
int OpcClient::writeShort(LPWSTR OPCServerProgID, LPWSTR groupID, LPWSTR szItemID, int value)
{
OpcClient::connectToServer(OPCServerProgID, groupID);
OpcClient::addItemtoGrp(szItemID, VT_I2);
OPCHANDLE *phServer;
HRESULT *pErrors;
VARIANT values[1];
HRESULT r1;
LPWSTR ErrorStr;
if (m_pErrors[0] != S_OK)
{
Stop();
return 1;
}
phServer = new OPCHANDLE[1];
phServer[0] = m_ItemResult[0].hServer;
values[0].vt = VT_I2;
values[0].intVal = value;
r1 = m_IOPCSyncIO->Write(1, phServer, values, &pErrors);
delete[]phServer;
Stop();
return 0;
}
float OpcClient::readFloat(LPWSTR OPCServerProgID, LPWSTR groupID, LPWSTR szItemID, VARTYPE vt_ItemType)
{
OpcClient::connectToServer(OPCServerProgID, groupID);
OpcClient::addItemtoGrp(szItemID, vt_ItemType);
OPCHANDLE *phServer;
OPCITEMSTATE *pItemValue;
HRESULT *pErrors;
HRESULT r1 = E_FAIL;
if (m_pErrors[0] != S_OK)
{
return 32767;
}
//内存分配
phServer = new OPCHANDLE[1];
phServer[0] = m_ItemResult[0].hServer;
r1 = m_IOPCSyncIO->Read(OPC_DS_DEVICE, 1, phServer, &pItemValue, &pErrors);
//释放内存
delete[]phServer;
if (r1 == S_OK)
{
//
}
Stop();
return pItemValue[0].vDataValue.fltVal;
}
int OpcClient::writeFloat(LPWSTR OPCServerProgID, LPWSTR groupID, LPWSTR szItemID, float value)
{
OpcClient::connectToServer(OPCServerProgID, groupID);
OpcClient::addItemtoGrp(szItemID, VT_R4);
OPCHANDLE *phServer;
HRESULT *pErrors;
VARIANT values[1];
HRESULT r1;
LPWSTR ErrorStr;
if (m_pErrors[0] != S_OK)
{
return;
}
phServer = new OPCHANDLE[1];
phServer[0] = m_ItemResult[0].hServer;
//UpdateData(TRUE);
values[0].vt = VT_R4;
values[0].fltVal = value;
r1 = m_IOPCSyncIO->Write(1, phServer, values, &pErrors);
delete[]phServer;
Stop();
return 0;
}
bool OpcClient::readBool(LPWSTR OPCServerProgID, LPWSTR groupID, LPWSTR szItemID, VARTYPE vt_ItemType)
{
OpcClient::connectToServer(OPCServerProgID, groupID);
OpcClient::addItemtoGrp(szItemID, vt_ItemType);
OPCHANDLE *phServer;
OPCITEMSTATE *pItemValue;
HRESULT *pErrors;
HRESULT r1 = E_FAIL;
if (m_pErrors[0] != S_OK)
{
return 32767;
}
phServer = new OPCHANDLE[1];
phServer[0] = m_ItemResult[0].hServer;
r1 = m_IOPCSyncIO->Read(OPC_DS_DEVICE, 1, phServer, &pItemValue, &pErrors);
//释放内存
delete[]phServer;
if (r1 == S_OK)
{
//
}
Stop();
if (pItemValue[0].vDataValue.boolVal==-1)
{
return true;
}
else
{
return false;
}
}
int OpcClient::writeBool(LPWSTR OPCServerProgID, LPWSTR groupID, LPWSTR szItemID, bool value)
{
OpcClient::connectToServer(OPCServerProgID, groupID);
OpcClient::addItemtoGrp(szItemID, VT_R4);
OPCHANDLE *phServer;
HRESULT *pErrors;
VARIANT values[1];
HRESULT r1;
LPWSTR ErrorStr;
if (m_pErrors[0] != S_OK)
{
return;
}
phServer = new OPCHANDLE[1];
phServer[0] = m_ItemResult[0].hServer;
values[0].vt = VT_R4;
values[0].boolVal = value;
r1 = m_IOPCSyncIO->Write(1, phServer, values, &pErrors);
delete[]phServer;
Stop();
return 0;
}
int OpcClient::setBool(LPWSTR OPCServerProgID, LPWSTR groupID, LPWSTR szItemID, VARTYPE vt_ItemType)
{
writeBool(OPCServerProgID, groupID, szItemID, true);
if (readBool(OPCServerProgID, groupID, szItemID, VT_BOOL))
{
return 0;
}
else
{
return 1;
}
}
int OpcClient::resetBool(LPWSTR OPCServerProgID, LPWSTR groupID, LPWSTR szItemID, VARTYPE vt_ItemType)
{
writeBool(OPCServerProgID, groupID, szItemID, false);
if (readBool(OPCServerProgID, groupID, szItemID, VT_BOOL))
{
return 0;
}
else
{
return 1;
}
}
int OpcClient::invertBool(LPWSTR OPCServerProgID, LPWSTR groupID, LPWSTR szItemID, VARTYPE vt_ItemType)
{
if (readBool(OPCServerProgID, groupID, szItemID, VT_BOOL) == false)
{
writeBool(OPCServerProgID, groupID, szItemID, true);
return 0;
}
if (readBool(OPCServerProgID, groupID, szItemID, VT_BOOL) == true)
{
writeBool(OPCServerProgID, groupID, szItemID, false);
return 0;
}
}
int OpcClient::Stop()
{
if (OpcClientBusy == false)
{
return 1;
}
HRESULT r1;
OPCHANDLE *phServer;
HRESULT *pErrors;
phServer = new OPCHANDLE[1];
phServer[0] = m_ItemResult[0].hServer;
r1 = m_IOPCItemMgt->RemoveItems(0,
phServer,
&pErrors
);
delete[]phServer;
CoTaskMemFree(pErrors);
CoTaskMemFree(m_ItemResult);
m_ItemResult = NULL;
m_IOPCSyncIO->Release();
m_IOPCSyncIO = NULL;
m_IOPCItemMgt->Release();
m_IOPCItemMgt = NULL;
r1 = m_IOPCServer->RemoveGroup(m_GrpSrvHandle, true);
m_GrpSrvHandle = NULL;
m_IOPCServer->Release();
m_IOPCServer = NULL;
CoUninitialize();
OpcClientBusy = false;
return 0;
}
OpcClient::OpcClient()
{
OpcClientBusy = false;//初始化为false
}
OpcClient::~OpcClient()
{
//
}
mian函数
// OpcClient.cpp : 定义控制台应用程序的入口点。
#include "stdafx.h"
#include "OpcClient.h"
using namespace std;
OpcClient ObjKepOpc;
int _tmain(int argc, _TCHAR *argv[])
{
const LPWSTR OPCServerProgID = L"Kepware.KEPServerEX.V6";//服务器ProID
const LPWSTR groupID = L"King.Win7";//GroupID,通道.设备
const LPWSTR ritem_1 = L"King.Win7.Tag_1";//item格式,通道.设备.item
const LPWSTR ritem_2 = L"King.Win7.Tag_2";//item格式,通道.设备.item
const LPWSTR witem_1 = L"King.Win7.Tag_1_write";//item格式,通道.设备.item
const LPWSTR witem_2 = L"King.Win7.Tag_2_write";//item格式,通道.设备.item
ObjKepOpc.connectToServer(OPCServerProgID, groupID);
while(1)
{
//读
float r1 = ObjKepOpc.readFloat(OPCServerProgID, groupID,ritem_1, VT_R4);
float r2 = ObjKepOpc.readFloat(OPCServerProgID, groupID,ritem_2, VT_R4);
cout<< r1 <<endl;
cout<< r2 <<endl;
//写
ObjKepOpc.writeFloat(OPCServerProgID, groupID,witem_1,r1);
ObjKepOpc.writeFloat(OPCServerProgID, groupID,witem_2,r2);
}
return 0;
}
完整项目:
https://download.csdn.net/download/weixin_37928884/86881385