/// <summary> /// 断开连接,调用需要捕捉异常 /// </summary> public void DisConnect() //断开和OPCServer的连接,并释放内存 { try { isConnected = false; isAddGroup = false; isAddItems = false; if (IOPCSyncObj != null) { Marshal.ReleaseComObject(IOPCSyncObj); IOPCSyncObj = null; } ServerObj.RemoveGroup(pSvrGroupHandle, 0); if (GroupObj != null) { Marshal.ReleaseComObject(GroupObj); GroupObj = null; } if (ServerObj != null) { Marshal.ReleaseComObject(ServerObj); ServerObj = null; } } catch (System.Exception error) { MessageBox.Show(error.Message, "断开OPCServer连接出错", MessageBoxButtons.OK, MessageBoxIcon.Error); } }
private void Btn_DisConn_Click(object sender, EventArgs e) { try { if (IOPCSyncIO20Obj != null) { Marshal.ReleaseComObject(IOPCSyncIO20Obj); IOPCSyncIO20Obj = null; } ServerObj.RemoveGroup(pSvrGroupHandle, 0); if (IOPCGroupStateMgtObj != null) { Marshal.ReleaseComObject(IOPCGroupStateMgtObj); IOPCGroupStateMgtObj = null; } if (MyobjGroup1 != null) { Marshal.ReleaseComObject(MyobjGroup1); MyobjGroup1 = null; } if (ServerObj != null) { Marshal.ReleaseComObject(ServerObj); ServerObj = null; } } catch (System.Exception error) { MessageBox.Show(error.Message, "Result-Stop Server", MessageBoxButtons.OK, MessageBoxIcon.Error); } }
/// <summary> /// 初始化组对象 /// </summary> public bool AddGroup() //返回值false为失败,true为成功 { Int32 dwRequestedUpdateRate = 1000; Int32 hClientGroup = 1; Int32 pRevUpdaterate; float deadband = 0; int TimeBias = 0; GCHandle hTimeBias, hDeadband; hTimeBias = GCHandle.Alloc(TimeBias, GCHandleType.Pinned); hDeadband = GCHandle.Alloc(deadband, GCHandleType.Pinned); Guid iidRequiredInterface = typeof(IOPCItemMgt).GUID; if (!isConnected) { if (!Connect()) { return(false); //如果还没有没有建立连接,先建立连接 } } try { //ServerObj.AddGroup的返回值类型为void ServerObj.AddGroup("OPCGroup", 0, dwRequestedUpdateRate, hClientGroup, hTimeBias.AddrOfPinnedObject(), hDeadband.AddrOfPinnedObject(), LOCALE_ID, out pSvrGroupHandle, out pRevUpdaterate, ref iidRequiredInterface, out GroupObj); IOPCSyncObj = (IOPCSyncIO)GroupObj;//为组同步读写定义句柄 isAddGroup = true; } catch (System.Exception error) { isAddGroup = false; MessageBox.Show(string.Format("创建组对象时出错:-{0}", error.Message), "建组出错", MessageBoxButtons.OK, MessageBoxIcon.Error); } finally { if (hDeadband.IsAllocated) { hDeadband.Free(); } if (hTimeBias.IsAllocated) { hTimeBias.Free(); } } return(isAddGroup); }
int pSvrGroupHandle = 0; //OPCGroup句柄 //连接OPCServer,建立相应OPCGroup组,并添加需要读写的Item private void Btn_Conn_Click(object sender, EventArgs e) { //定义变量 Type svrComponenttype; Int32 dwRequestedUpdateRate = 1000; //订阅读取速度 Int32 hClientGroup = 1; Int32 pRevUpdateRate; OpcRcw.Da.OPCITEMDEF[] ItemArray; float deadband = 0; int TimeBias = 0; //使用C#托管代码时,内存地址和GC回收不需要关心,CLR已经给我们暗箱操作 //如果在C#中调用了非托管代码,比如VC的DLL,而且它有一个回调函数,需要引用C#中的某个对象并操作,这时候需要小心 //要是非托管代码中用到的托管代码那个对象被GC给回收了,这时候就会报内存错误 //所以就要把那个对象钉住"Pin",让它的内存地址固定,而不被垃圾回收掉,然后我们自己管理,自己释放内存,这时候就需要GCHandle GCHandle hTimeBias, hDeadband; hTimeBias = GCHandle.Alloc(TimeBias, GCHandleType.Pinned); hDeadband = GCHandle.Alloc(deadband, GCHandleType.Pinned); Guid iidRequiredInterface = typeof(IOPCItemMgt).GUID; try { svrComponenttype = Type.GetTypeFromProgID("OPC.SimaticNet", "192.168.0.102"); //OPCServer ServerObj = (OpcRcw.Da.IOPCServer)Activator.CreateInstance(svrComponenttype); //注册 try { ServerObj.AddGroup("MyOPCGroup1", //增加组 0, dwRequestedUpdateRate, hClientGroup, hTimeBias.AddrOfPinnedObject(), hDeadband.AddrOfPinnedObject(), LOCALE_ID, out pSvrGroupHandle, out pRevUpdateRate, ref iidRequiredInterface, out MyobjGroup1); IOPCSyncIO20Obj = (IOPCSyncIO)MyobjGroup1; //Query interface for sync calls on group object IOPCGroupStateMgtObj = (IOPCGroupStateMgt)MyobjGroup1; ItemArray = new OPCITEMDEF[2]; //定义读写的item,共2个变量 ItemArray[0].szAccessPath = ""; ItemArray[0].szItemID = "S7:[S7 conncetion_1]DB10,INT0"; //地址,不同数据类型表示方法不同 ItemArray[0].bActive = 1; //是否激活 ItemArray[0].hClient = 1; //表示ID ItemArray[0].dwBlobSize = 0; ItemArray[0].vtRequestedDataType = 2; ItemArray[1].szAccessPath = ""; ItemArray[1].szItemID = "S7:[S7 connection_1]DB10,STRING14.10"; ItemArray[1].bActive = 1; ItemArray[1].hClient = 2; ItemArray[1].dwBlobSize = 0; ItemArray[1].pBlob = IntPtr.Zero; ItemArray[1].vtRequestedDataType = 8; IntPtr pResults = IntPtr.Zero; IntPtr pErrors = IntPtr.Zero; try { ((OpcRcw.Da.IOPCItemMgt)MyobjGroup1).AddItems(2, ItemArray, out pResults, out pErrors); int[] errors = new int[2]; IntPtr pos = pResults; ItemServerHandle = new int[2]; Marshal.Copy(pErrors, errors, 0, 2); if (errors[0] == 0) { OPCITEMRESULT result = (OPCITEMRESULT)Marshal.PtrToStructure(pos, typeof(OPCITEMRESULT)); ItemServerHandle[0] = result.hServer; } if (errors[1] == 0) { pos = new IntPtr(pos.ToInt32() + Marshal.SizeOf(typeof(OPCITEMRESULT))); OPCITEMRESULT result = (OPCITEMRESULT)Marshal.PtrToStructure(pos, typeof(OPCITEMRESULT)); ItemServerHandle[1] = result.hServer; } } catch (System.Exception error) { MessageBox.Show(error.Message, "Result-Adding Items", MessageBoxButtons.OK, MessageBoxIcon.Error); } finally { //free the memory if (pResults != IntPtr.Zero) { Marshal.FreeCoTaskMem(pResults); pResults = IntPtr.Zero; } if (pErrors != IntPtr.Zero) { Marshal.FreeCoTaskMem(pErrors); pErrors = IntPtr.Zero; } } } catch (System.Exception error) { MessageBox.Show(String.Format("Error while creating group object:-{0}", error.Message), "Result-Add group", MessageBoxButtons.AbortRetryIgnore, MessageBoxIcon.Error); } finally { if (hDeadband.IsAllocated) { hDeadband.Free(); } if (hTimeBias.IsAllocated) { hTimeBias.Free(); } } } catch (System.Exception error) { MessageBox.Show(String.Format("Error while creating server object:-{0}", error.Message), "Result-Create Server", MessageBoxButtons.AbortRetryIgnore, MessageBoxIcon.Error); } }