上次研究了.Net版本的OPC API dll,这次我采用OPCDAAuto.dll来介绍使用方法。
以下为我的源代码,有详细的注释无需我多言。
编译平台:VS2008SP1、WINXP、KEPServer
除此之外,我也安装了西门子的Net2006和Step7,其中Net2006是负责OPC的,可能会在系统中创建一些dll之类的,并提供几个OPC服务器
以下是我Program.cs(基于控制台的)的全部内容,仍旧采用C#语言:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Collections;
using OPCAutomation;
using System.Threading; namespace OPCDAAutoTest
{
class Tester
{
static void Main(string[] args)
{
Tester tester=new Tester();
tester.work();
}
#region 私有变量
/// <summary>
/// OPCServer Object
/// </summary>
OPCServer MyServer;
/// <summary>
/// OPCGroups Object
/// </summary>
OPCGroups MyGroups;
/// <summary>
/// OPCGroup Object
/// </summary>
OPCGroup MyGroup;
OPCGroup MyGroup2;
/// <summary>
/// OPCItems Object
/// </summary>
OPCItems MyItems;
OPCItems MyItems2;
/// <summary>
/// OPCItem Object
/// </summary>
OPCItem[] MyItem;
OPCItem[] MyItem2;
/// <summary>
/// 主机IP
/// </summary>
string strHostIP = "";
/// <summary>
/// 主机名称
/// </summary>
string strHostName = "";
/// <summary>
/// 连接状态
/// </summary>
bool opc_connected = false;
/// <summary>
/// 客户端句柄
/// </summary>
int itmHandleClient = ;
/// <summary>
/// 服务端句柄
/// </summary>
int itmHandleServer = ;
#endregion
//测试用工作方法
public void work()
{
//初始化item数组
MyItem = new OPCItem[];
MyItem2 = new OPCItem[]; GetLocalServer();
//ConnectRemoteServer("TX1", "KEPware.KEPServerEx.V4");//用计算机名的局域网
//ConnectRemoteServer("192.168.1.35", "KEPware.KEPServerEx.V4");//用IP的局域网
if (ConnectRemoteServer("", "KEPware.KEPServerEx.V4"))//本机
{
if (CreateGroup())
{
Thread.Sleep();//暂停线程以让DataChange反映,否则下面的同步读可能读不到
//以下同步写
MyItem[].Write("I love you!");//同步写
MyItem[].Write(true);//同步写
MyItem[].Write(-);//同步写
MyItem[].Write();//同步写 //以下同步读
object ItemValues; object Qualities; object TimeStamps;//同步读的临时变量:值、质量、时间戳
MyItem[].Read(,out ItemValues,out Qualities,out TimeStamps);//同步读,第一个参数只能为1或2
int q0 = Convert.ToInt32(ItemValues);//转换后获取item值
MyItem[].Read(, out ItemValues, out Qualities, out TimeStamps);//同步读,第一个参数只能为1或2
int q1 = Convert.ToInt32(ItemValues);//转换后获取item值
MyItem[].Read(, out ItemValues, out Qualities, out TimeStamps);//同步读,第一个参数只能为1或2
bool q2 = Convert.ToBoolean(ItemValues);//转换后获取item值
MyItem[].Read(, out ItemValues, out Qualities, out TimeStamps);//同步读,第一个参数只能为1或2
string q3 = Convert.ToString(ItemValues);//转换后获取item值,为防止读到的值为空,不用ItemValues.ToString() Console.WriteLine("~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
Console.WriteLine("0-{0},1-{1},2-{2},3-{3}",q0,q1,q2,q3); //以下为异步写
//异步写时,Array数组从下标1开始而非0!
int[] temp = new int[] { ,MyItem[].ServerHandle,MyItem[].ServerHandle,MyItem[].ServerHandle, MyItem[].ServerHandle };
Array serverHandles = (Array)temp;
object[] valueTemp = new object[] { "",,,true, "Love" };
Array values = (Array)valueTemp;
Array Errors;
int cancelID;
MyGroup.AsyncWrite(, ref serverHandles, ref values, out Errors, , out cancelID);//第一参数为item数量
//由于MyGroup2没有订阅,所以以下这句运行时将会出错!
//MyGroup2.AsyncWrite(4, ref serverHandles, ref values, out Errors, 1, out cancelID); //以下异步读
MyGroup.AsyncRead(, ref serverHandles, out Errors, , out cancelID);//第一参数为item数量 /*MyItem[0] = MyItems.AddItem("BPJ.Db1.dbb96", 0);//byte
MyItem[1] = MyItems.AddItem("BPJ.Db1.dbw10", 1);//short
MyItem[2] = MyItems.AddItem("BPJ.Db16.dbx0", 2);//bool
MyItem[3] = MyItems.AddItem("BPJ.Db11.S0", 3);//string*/ Console.WriteLine("************************************** hit <return> to Disconnect...");
Console.ReadLine();
//释放所有组资源
MyServer.OPCGroups.RemoveAll();
//断开服务器
MyServer.Disconnect();
}
} //END
Console.WriteLine("************************************** hit <return> to close...");
Console.ReadLine();
}
//枚举本地OPC服务器
private void GetLocalServer()
{
//获取本地计算机IP,计算机名称
strHostName = Dns.GetHostName();
//或者通过局域网内计算机名称
strHostName = "TX1"; //获取本地计算机上的OPCServerName
try
{
MyServer = new OPCServer();
object serverList = MyServer.GetOPCServers(strHostName); foreach (string server in (Array)serverList)
{
//cmbServerName.Items.Add(turn);
Console.WriteLine("本地OPC服务器:{0}", server);
}
}
catch (Exception err)
{
Console.WriteLine("枚举本地OPC服务器出错:{0}",err.Message);
}
}
//连接OPC服务器
/// <param name="remoteServerIP">OPCServerIP</param>
/// <param name="remoteServerName">OPCServer名称</param>
private bool ConnectRemoteServer(string remoteServerIP, string remoteServerName)
{
try
{
MyServer.Connect(remoteServerName, remoteServerIP);//连接本地服务器:服务器名+主机名或IP if (MyServer.ServerState == (int)OPCServerState.OPCRunning)
{
Console.WriteLine("已连接到:{0}",MyServer.ServerName);
}
else
{
//这里你可以根据返回的状态来自定义显示信息,请查看自动化接口API文档
Console.WriteLine("状态:{0}",MyServer.ServerState.ToString());
}
MyServer.ServerShutDown+=ServerShutDown;//服务器断开事件
}
catch (Exception err)
{
Console.WriteLine("连接远程服务器出现错误:{0}" + err.Message);
return false;
}
return true;
}
//创建组
private bool CreateGroup()
{
try
{
MyGroups = MyServer.OPCGroups;
MyGroup = MyServer.OPCGroups.Add("测试");//添加组
MyGroup2 = MyGroups.Add("测试2");
OPCGroup MyGroup3 = MyGroups.Add("测试3");//测试删除组
//以下设置组属性
{
MyServer.OPCGroups.DefaultGroupIsActive = true;//激活组。
MyServer.OPCGroups.DefaultGroupDeadband = ;// 死区值,设为0时,服务器端该组内任何数据变化都通知组。
MyServer.OPCGroups.DefaultGroupUpdateRate = ;//默认组群的刷新频率为200ms
MyGroup.UpdateRate = ;//刷新频率为1秒。
MyGroup.IsSubscribed = true;//使用订阅功能,即可以异步,默认false
} MyGroup.DataChange += new DIOPCGroupEvent_DataChangeEventHandler(GroupDataChange);
MyGroup.AsyncWriteComplete += new DIOPCGroupEvent_AsyncWriteCompleteEventHandler(GroupAsyncWriteComplete);
MyGroup.AsyncReadComplete += new DIOPCGroupEvent_AsyncReadCompleteEventHandler(GroupAsyncReadComplete);
//由于MyGroup2.IsSubscribed是false,即没有订阅,所以以下的DataChange回调事件不会发生!
MyGroup2.DataChange += new DIOPCGroupEvent_DataChangeEventHandler(GroupDataChange2);
MyGroup.AsyncWriteComplete += new DIOPCGroupEvent_AsyncWriteCompleteEventHandler(GroupAsyncWriteComplete); MyServer.OPCGroups.Remove("测试3");//移除组
AddGroupItems();//设置组内items
}
catch (Exception err)
{
Console.WriteLine("创建组出现错误:{0}", err.Message);
return false;
}
return true;
}
private void AddGroupItems()//添加组
{
//itmHandleServer;
MyItems = MyGroup.OPCItems;
MyItems2 = MyGroup2.OPCItems; //添加item
MyItem[] = MyItems.AddItem("BPJ.Db1.dbb96", );//byte
MyItem[] = MyItems.AddItem("BPJ.Db1.dbw10", );//short
MyItem[] = MyItems.AddItem("BPJ.Db16.dbx0", );//bool
MyItem[] = MyItems.AddItem("BPJ.Db11.S0", );//string
//移除组内item
Array Errors;
int []temp=new int[]{,MyItem[].ServerHandle};
Array serverHandle = (Array)temp;
MyItems.Remove(, ref serverHandle, out Errors);
MyItem[] = MyItems.AddItem("BPJ.Db11.S0", );//string MyItem2[] = MyItems2.AddItem("BPJ.Db1.dbb96", );//byte
MyItem2[] = MyItems2.AddItem("BPJ.Db1.dbw10", );//short
MyItem2[] = MyItems2.AddItem("BPJ.Db16.dbx0", );//bool
MyItem2[] = MyItems2.AddItem("BPJ.Db11.S0", );//string }
public void ServerShutDown(string Reason)//服务器先行断开
{
Console.WriteLine("服务器已经先行断开!");
}
/// <summary>
/// 每当项数据有变化时执行的事件
/// </summary>
/// <param name="TransactionID">处理ID</param>
/// <param name="NumItems">项个数</param>
/// <param name="ClientHandles">项客户端句柄</param>
/// <param name="ItemValues">TAG值</param>
/// <param name="Qualities">品质</param>
/// <param name="TimeStamps">时间戳</param>1 `
void GroupDataChange(int TransactionID, int NumItems, ref Array ClientHandles, ref Array ItemValues, ref Array Qualities, ref Array TimeStamps)
{
Console.WriteLine("++++++++++++++++DataChanged+++++++++++++++++++++++");
/*for (int i = 1; i <= NumItems; i++)
{
Console.WriteLine("item值:{0}", ItemValues.GetValue(i).ToString());
//Console.WriteLine("item句柄:{0}", ClientHandles.GetValue(i).ToString());
//Console.WriteLine("item质量:{0}", Qualities.GetValue(i).ToString());
//Console.WriteLine("item时间戳:{0}", TimeStamps.GetValue(i).ToString());
//Console.WriteLine("item类型:{0}", ItemValues.GetValue(i).GetType().FullName);
}*/
}
void GroupDataChange2(int TransactionID, int NumItems, ref Array ClientHandles, ref Array ItemValues, ref Array Qualities, ref Array TimeStamps)
{
Console.WriteLine("----------------------DataChanged2------------------");
/*for (int i = 1; i <= NumItems; i++)
{
Console.WriteLine("item2值:{0}", ItemValues.GetValue(i).ToString());
//Console.WriteLine("item2质量:{0}", Qualities.GetValue(i).ToString());
//Console.WriteLine("item2时间戳:{0}", TimeStamps.GetValue(i).ToString());
}*/
}
/// <summary>
/// 异步写完成
/// 运行时,Array数组从下标1开始而非0!
/// </summary>
/// <param name="TransactionID"></param>
/// <param name="NumItems"></param>
/// <param name="ClientHandles"></param>
/// <param name="Errors"></param>
void GroupAsyncWriteComplete(int TransactionID, int NumItems, ref Array ClientHandles, ref Array Errors)
{
Console.WriteLine("%%%%%%%%%%%%%%%%AsyncWriteComplete%%%%%%%%%%%%%%%%%%%");
/*for (int i = 1; i <= NumItems; i++)
{
Console.WriteLine("Tran:{0} ClientHandles:{1} Error:{2}", TransactionID.ToString(), ClientHandles.GetValue(i).ToString(), Errors.GetValue(i).ToString());
}*/
} /// <summary>
/// 异步读完成
/// 运行时,Array数组从下标1开始而非0!
/// </summary>
/// <param name="TransactionID"></param>
/// <param name="NumItems"></param>
/// <param name="ClientHandles"></param>
/// <param name="ItemValues"></param>
/// <param name="Qualities"></param>
/// <param name="TimeStamps"></param>
/// <param name="Errors"></param>
void GroupAsyncReadComplete(int TransactionID, int NumItems, ref System.Array ClientHandles, ref System.Array ItemValues, ref System.Array Qualities, ref System.Array TimeStamps, ref System.Array Errors)
{
Console.WriteLine("****************GroupAsyncReadComplete*******************");
for (int i = ; i <= NumItems; i++)
{
//Console.WriteLine("Tran:{0} ClientHandles:{1} Error:{2}", TransactionID.ToString(), ClientHandles.GetValue(i).ToString(), Errors.GetValue(i).ToString());
Console.WriteLine("Vaule:{0}",Convert.ToString(ItemValues.GetValue(i)));
}
}
}
}

OPCDAAuto.dll的C#使用方法浅析的更多相关文章

  1. OPCDAAuto.dll的C#使用方法浅析(转载)

    上次研究了.Net版本的OPC API dll,这次我采用OPCDAAuto.dll来介绍使用方法.以下为我的源代码,有详细的注释无需我多言.编译平台:VS2008SP1.WINXP.KEPServe ...

  2. Java调用第三方dll文件的使用方法 System.load()或System.loadLibrary()

    Java调用第三方dll文件的使用方法 public class OtherAdapter { static { //System.loadLibrary("Connector") ...

  3. 启动 Eclipse 弹出“Failed to load the JNI shared library jvm.dll”错误的解决方法!&&在eclipse.ini中为eclipse指定jdk启动

    参考:http://blog.csdn.net/zyz511919766/article/details/7442633 http://blog.sina.com.cn/s/blog_028f0c1c ...

  4. 启动 Eclipse 弹出“Failed to load the JNI shared library jvm.dll”错误的解决方法!

    启动 Eclipse 弹出"Failed to load the JNI shared library jvm.dll"错误的解决方法 http://blog.csdn.net/z ...

  5. 使用OPCDAAuto.dll编写C# OPC采集程序

    在一台新机器上运行使用OPC自动化接口编写的C#程序报错如下: 索 COM 类工厂中 CLSID 为 {28E68F9A-8D75-11D1-8DC3-3C302A000000} 的组件失败,原因是出 ...

  6. C++调用DLL有两种方法——静态调用和动态调用

    C++调用DLL有两种方法——静态调用和动态调用 标签: dllc++winapinullc 2011-09-09 09:49 11609人阅读 评论(0) 收藏 举报  分类: cpp(30)  [ ...

  7. C# Winform窗口之间传值的多种方法浅析(转)

    摘要http://www.jb51.net/article/63837.htm 这篇文章主要介绍了C# Winform窗口之间传值的多种方法浅析,本文起讲解了通过构造器传值.通过属性传递.通过事件携带 ...

  8. 关于opcdaauto.dll的注册

    关于opcdaauto.dll的注册 无论win7_32还是win7_64位都执行一样的CMD命令,即regsvr32 opcdaauto.dll . 如果从网上下载的opcdaauto.dll 文件 ...

  9. python2在安装pywin32后出现ImportError: DLL load failed 解决方法

    python2在安装pywin32后出现ImportError: DLL load failed 解决方法 在python2中有时候会出现: import win32api   ImportError ...

随机推荐

  1. 配置阿里云maven中央库

    <mirrors> <mirror> <id>nexus-aliyun</id> <mirrorOf>*</mirrorOf> ...

  2. spring配置mq入门案例

    第一步:添加maven配置 <!-- mq --> <dependency> <groupId>org.springframework</groupId> ...

  3. 理解Java中字符流与字节流的区别(转)

    1. 什么是流 Java中的流是对字节序列的抽象,我们可以想象有一个水管,只不过现在流动在水管中的不再是水,而是字节序列.和水流一样,Java中的流也具有一个“流动的方向”,通常可以从中读入一个字节序 ...

  4. Entity Framework 6 Code First 系列:无需修改实体和配置-在MySql中使用和SqlServer一致的并发控制

    无需修改实体和配置,在MySql中使用和SqlServer一致的并发控制.修改RowVersion类型不可取,修改为Timestamp更不可行.Sql Server的RowVersion生成一串唯一的 ...

  5. django Models 常用的字段和参数

    1.字段 CharField IntegerField floatField DateTimeField DateField DecimalField 2.参数 null default choice ...

  6. Learining TypeScript (一) TypeScript 简介

    Learining TypeScript (一) TypeScript 简介 一.TypeScript出现的背景    2 二.TypeScript的架构    2 1.    设计目标    2 2 ...

  7. javascript简单介绍总结(一)

    DOM (Document Object Model)(文档对象模型)是用于访问 HTML 元素的正式 W3C 标准.在 HTML 中,JavaScript 语句向浏览器发出的命令.语句是用分号分隔: ...

  8. (CSharp)克隆控件事件

    // https://stackoverflow.com/questions/6055038/how-to-clone-control-event-handlers-at-run-time // &q ...

  9. MySQL-5.7复制功能的默认设置改进

    1. 默认开启简化的GTID 恢复 Binlog_gtid_simple_recovery=TURE(默认值)      这个参数控制了当mysql启动或重启时,mysql在搜寻GTIDs时是如何迭代 ...

  10. 八行代码解决八皇后问题(c++)

    说的有点夸装,实际上并不只是巴航代码,加上前面的变量声明之类的一共有40多行的样子吧,好像是在知乎上看到的,现在有时间再把它写下来: 其中用到了一些c++11特性,例如lambda 以及给予范围的 f ...