-
Notifications
You must be signed in to change notification settings - Fork 6
/
OPCDAClientSync.cpp
142 lines (113 loc) · 3.46 KB
/
OPCDAClientSync.cpp
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
135
136
137
138
139
140
141
142
#pragma once
#include "OPCDAClientSync.h"
#include <exception>
void OPCDAClientSync::Initialize ()
{
HRESULT result = CoInitialize(NULL);
if (FAILED(result))
{
throw std::exception("CoInitialize failed");
}
result = CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_NONE, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL);
if (FAILED(result))
{
throw std::exception("CoInitializeSecurity failed");
}
}
void OPCDAClientSync::Uninitialize ()
{
CoUninitialize();
}
OPCDAClientSync::OPCDAClientSync (const std::wstring & serverProgID)
{
CComBSTR server_prog_id = serverProgID.c_str();
ATL::CComPtr<IOPCServer> pIOPCServer;
HRESULT result = pIOPCServer.CoCreateInstance(server_prog_id);
if (FAILED (result))
{
throw std::exception ("CoCreateInstance IOPCServer failed");
}
CComBSTR group_name = L"group";
OPCHANDLE group_handle = 0;
DWORD group_revised_updaterate = 0;
ATL::CComPtr<IOPCGroupStateMgt> pIOPCGroupStateMgt;
result = pIOPCServer->AddGroup (group_name, FALSE, 1000, 0, NULL, NULL, 0, &group_handle, &group_revised_updaterate, __uuidof(IOPCGroupStateMgt), ( LPUNKNOWN * ) &pIOPCGroupStateMgt);
if (FAILED (result))
{
throw std::exception ("AddGroup failed");
}
ATL::CComPtr<IOPCSyncIO> pIOPCSyncIO;
result = pIOPCGroupStateMgt.QueryInterface (&pIOPCSyncIO);
if (FAILED (result))
{
throw std::exception ("QueryInterface IID_IOPCSyncIO failed");
}
ATL::CComPtr<IOPCItemMgt> pIOPCItemMgt;
result = pIOPCGroupStateMgt.QueryInterface (&pIOPCItemMgt);
if (FAILED (result))
{
throw std::exception ("QueryInterface IID_IOPCItemMgt failed");
}
m_pIOPCSyncIO.Attach(pIOPCSyncIO.Detach());
m_pIOPCItemMgt.Attach(pIOPCItemMgt.Detach());
m_pIOPCServer.Attach(pIOPCServer.Detach());
m_server_handles.clear ();
};
void OPCDAClientSync::AddItem (const std::wstring & name)
{
CComBSTR item_name = name.c_str();
static OPCHANDLE next_item_client_handle = 1;
OPCITEMDEF def = { 0 };
def.szItemID = item_name;
def.hClient = next_item_client_handle++;
OPCITEMRESULT * addresult = nullptr;
HRESULT * hresult = nullptr;
HRESULT result = m_pIOPCItemMgt->AddItems (1, &def, &addresult, &hresult);
if (FAILED (result))
{
throw std::exception ("AddItems failed");
}
m_server_handles.emplace (name, addresult->hServer);
CoTaskMemFree (addresult);
CoTaskMemFree (hresult);
};
std::wstring OPCDAClientSync::ReadItem (const std::wstring & name)
{
if (!m_server_handles.count (name))
{
AddItem (name);
}
OPCHANDLE serverHandles = m_server_handles.at(name);
OPCITEMSTATE * itemState;
HRESULT * itemResult;
HRESULT result = m_pIOPCSyncIO->Read (OPCDATASOURCE::OPC_DS_DEVICE, 1, &serverHandles, &itemState, &itemResult);
if (FAILED (result))
{
throw std::exception ("Read failed");
}
result = VariantChangeType (&itemState->vDataValue, &itemState->vDataValue, 0, VT_BSTR);
if (FAILED (result))
{
throw std::exception ("VariantChangeType failed");
}
std::wstring ret = itemState->vDataValue.bstrVal;
CoTaskMemFree (itemResult);
VariantClear (&itemState->vDataValue);
CoTaskMemFree (itemState);
return ret;
};
void OPCDAClientSync::WriteItem (const std::wstring & name, const std::wstring & val)
{
if (!m_server_handles.count (name))
{
AddItem (name);
}
OPCHANDLE serverHandles = m_server_handles.at(name);
CComVariant value = val.c_str();
HRESULT * itemResult;
HRESULT result = m_pIOPCSyncIO->Write(1, &serverHandles, &value, &itemResult);
if (FAILED(result)){
throw std::exception("Write failed");
}
CoTaskMemFree (itemResult);
}