OPC core components 介绍及下载
Proxy/stub:
OpcDaAuto.dll |
OPC Data Access Automation Wrapper |
Opcproxy.dll |
OPC Data Access 3.00 Proxy/Stub |
OpcComn_ps.dll |
OPC Common 1.10 Proxy/Stub |
Opc_aeps.dll |
OPC Alarms & Events 1.10 Proxy/Stub |
Opchda_ps.dll |
OPC Historial Data Access 1.20 Proxy/Stub |
opcEnum.exe |
OPC Server Enumerator 1.10 |
.NET wrapper:
OpcRcw下载
OpcRcw.Da.dll |
OPC Data Access 3.00 .NET Wrapper |
OpcRcw.Ae.dll |
OPC Alarms & Events 1.10 .NET Wrapper |
OpcRcw.Hda.dll |
OPC Historial Data Access 1.20 .NET Wrapper |
OpcRcw.Comn.dll |
OPC Common 1.10 .NET Wrapper |
OpcRcw.Batch.dll |
OPC batch custom 2.0 .NET Wrapper |
OpcRcw.Dx.dll |
OPC Data eXchange 1.0 .NET Wrapper |
Include files:
Opcda.idl
Opcda.h
Opcda_i.c
Opcerror.h
Opccomn.idl
Opccomn.h
Opccomn_i.c
OpcProxy.dll如何生成的
工程文件:
Opcda.idl: 接口定义文件;
opcda.h, opcda_i.c, opcda_p.c, dlldata.c都是有opcda.idl编译生成;
Opcerror.h: opc da 错误代码定义;
Opcerror.mc: opc da 错误代码对应的文本描述,格式如下:
MessageID=0x0006
Severity=Error
Facility=Interface
SymbolicName=OPC_E_BADRIGHTS
Language=English
The item's access rights do not allow the operation.
OpcEnum.exe
是一个Windows 服务程序,通过DCOM方式,让client获得远程机器上有哪些OPC server可以访问。OpcEnum实现IOPCServerList接口,该接口定义如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
{
HRESULT EnumClassesOfCategories(
[in] ULONG cImplemented,
[in,size_is(cImplemented)] CATID rgcatidImpl[],
[in] ULONG cRequired,
[in,size_is(cRequired)] CATID rgcatidReq[],
[out] IEnumGUID ** ppenumClsid
);
HRESULT GetClassDetails(
[in] REFCLSID clsid,
[out] LPOLESTR* ppszProgID,
[out] LPOLESTR* ppszUserType
);
HRESULT CLSIDFromProgID(
[in] LPCOLESTR szProgId,
[out] LPCLSID clsid
);
};
Opc Client可以通过如下方式枚举远程OPC server:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
MULTI_QI mqi;
COSERVERINFO sin;
CComPtr<IOPCServerList> spServerList = NULL;
WCHAR wszNodeName[256];
memset( wszNodeName, 0, 256 );
// remote node name
//wcscpy(wszNodeName, L"RemoteComputerName");
// create opc server list object
if( wcslen(wszNodeName) <= 0 )
{
// local server enumerate
hr = CoCreateInstance( CLSID_OPCServerList, NULL, CLSCTX_ALL,
__uuidof( IOPCServerList), (LPVOID *) &spServerList );
if( FAILED( hr ) )
{
TRACE( L"Error: Could not load local OPC Server Enumerator Object" );
return;
}
}
else
{
sin.dwReserved1 = 0;
sin.dwReserved2 = 0;
sin.pwszName = wszNodeName;
sin.pAuthInfo = NULL;
mqi.pIID = &__uuidof(IOPCServerList);
mqi.hr = 0;
mqi.pItf = 0;
hr = CoCreateInstanceEx( CLSID_OPCServerList, NULL, CLSCTX_REMOTE_SERVER, &sin, 1, &mqi );
if( FAILED(hr) || FAILED(mqi.hr) )
{
TRACE( L"Error: Could not load OPC Server Enumerator Object" );
return;
}
spServerList = (IOPCServerList *) mqi.pItf;
}
// enumerate server list
IEnumGUID *pEnumGUID = NULL;
CLSID clsId;
DWORD count;
LPOLESTR szProgId, szUserType;
CLSID catId = CATID_OPCDAServer20;
hr = spServerList->EnumClassesOfCategories( 1, &catId, 1, &catId, &pEnumGUID );
if( FAILED( hr ) )
return;
while( SUCCEEDED( pEnumGUID->Next( 1, &clsId, &count ) ) )
{
hr = spServerList->GetClassDetails( clsId, &szProgId, &szUserType );
if( FAILED( hr ) )
return;
// do your own things with zProgId
// TODO
// probably want to save the class id in the item data field for this entry.
CoTaskMemFree( szProgId );
CoTaskMemFree( szUserType );
}