发表于:2008-08-03 13:03:10
楼主
http://www.opcfoundation.org/上的例子。现在把它们拿出来吧,大家有兴趣的可以跟我联系,不过事先说好啊,这些代码可不是免费的哦。要是需要到http://www.opcfoundation.org/下载别的资料,也可以找我们有偿服务。
请认准OPCFan@163.com品牌哦。
OPC UA SDK 1.00 Sample Source Code Setup (x86) 500元:
OPC DA 3.00 sample code 3.50 : 200.00元
OPC XMLDA 1.00 sample code :200.00元
OPC AE 1.10sample code 2.40: 150.00元
OPC HDA 1.20 sample code 4.10:150.00元
OPC batch 2.00 sample code :150.00元
OPC Security 1【1】.00 Sample CODE:150元
OPC Core Components Source Code :100元
另外附赠OPC相关规范文档,VC、VB客户端源代码, .Net API dlls.
有意者请与我们联系:QQ:564166173 和 250561779
E-mail: opcfan@163.com
MSN: zgjcc@hotmail.com
OPCDAAuto.dll是一个支持双接口的一个包装(Wrapper)。平常我们用VB在引用里调用,实际上用VC++也是可以的,只是范例比较少。OPCDAatuo.dll是用ATL(活动模板语言)开发,采用多重继承的方式实现服务器对象(Server)、OPC组对象(Group)和数据项(Item)等对象。
在这里先解释VB代码中的:
Set AnOPCServer = New OPCServer
AllOPCServers = AnOPCServer.GetOPCServers
中的GetServers方法的具体实现,调用过程大致如下:
1、在调用CreateEnumerator函数的时候,获得OPCEnum.exe的IOPCServerList2接口指针。在这里又分为访问本机和远程计算机的2种情况,通过GetOPCServers参数VARIANT Node来区分。
2、通过调用IOPCServerList2的EnumClassesOfCategories方法,可以获得DA1.0和DA2.0OPC服务器的CLSID枚举器指针ipEnumerator。
3、调用枚举器指针ipEnumerator的Next方法遍历所有的CLSID,并调用GetClassDetails把CLSID转换成ProgID等信息。
4、假如服务器端并没有安装OPCEnum.exe,或者没有注册,以上方法就会失败。在以上方法失败的情况下 即if (FAILED(hResult))
则直接查询目标计算机上的注册表上的“OPC”键,从而获得OPC服务器的ProgID。
补充说明,OPCEnum.exe的本质也是调用另外一个叫COMCAT.dll里的API函数来实现关键接口函数的。它可以注册为windows的一个服务。
具体代码如下:
STDMETHODIMP COPCAutoServer::GetOPCServers(VARIANT Node, VARIANT* pOPCServers)
{
USES_CONVERSION;
TRACE_FUNCTION_ENTER("COPCAutoServer::GetOPCServers");
if (!CheckByValInVariantArg(Node, VT_BSTR, true)) return E_INVALIDARG;
if (!CheckByRefOutArg(pOPCServers)) return E_INVALIDARG;
list<CComBSTR*> cProgIDs;
LPTSTR tsNodeName = NULL;
if ((Node.vt == VT_BSTR) && (Node.bstrVal != NULL) && (Node.bstrVal【0】 != 0))
{
tsNodeName = OLE2T(Node.bstrVal);
}
HRESULT hResult = E_FAIL;
// connect to OPC server enumerator.
IOPCServerList2* ipEnumerator = CreateEnumerator(CLSID_OpcServerList, tsNodeName);
if (ipEnumerator != NULL)
{
// enumerate all DA 1.0a and DA 2.0 servers.
IOPCEnumGUID* ipEnumGUID = NULL;
CATID cCatids【2】;
cCatids【0】 = CATID_OPCDAServer10;
cCatids【1】 = CATID_OPCDAServer20;
TRACE_METHOD_CALL(EnumClassesOfCategories);
hResult = ipEnumerator->EnumClassesOfCategories(2, cCatids, 0, NULL, &ipEnumGUID);
if (SUCCEEDED(hResult))
{
CLSID pClsids【BLOCK_SIZE】;
memset(pClsids, 0, sizeof(pClsids));
do
{
DWORD dwCount = 0;
hResult = ipEnumGUID->Next(BLOCK_SIZE, pClsids, &dwCount);
if (FAILED(hResult) || dwCount == 0)
{
hResult = S_OK;
break;
}
for (DWORD ii = 0; ii < dwCount; ii++)
{
LPWSTR szProgID = NULL;
LPWSTR szUserType = NULL;
LPWSTR szVerIndProgID = NULL;
hResult = ipEnumerator->GetClassDetails(pClsids【ii】, &szProgID, &szUserType, &szVerIndProgID);
if (SUCCEEDED(hResult))
{
cProgIDs.push_back(new CComBSTR(szProgID));
CoTaskMemFree(szProgID);
CoTaskMemFree(szUserType);
CoTaskMemFree(szVerIndProgID);
}
}
}
while (SUCCEEDED(hResult));
ipEnumGUID->Release();
}