예제 #1
0
파일: Form1.cs 프로젝트: RonaldShen/OPC
 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);
     }
 }
예제 #2
0
파일: Form1.cs 프로젝트: RonaldShen/OPC
        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);
            }
        }
예제 #3
0
        /// <summary>
        /// 添加组和标签异步读取
        /// </summary>
        /// <param name="name"></param>
        public static void OPCServerADDgroup(string name, string itemname)
        {
            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 (connectedOK == false)
            {
                MessageBox.Show("OPC服务器没有连接,读取数据失败");
                return;
            }
            IntPtr pResults = IntPtr.Zero;                                                  /* 保存AddItems函数的执行结果 */
            IntPtr pErrors  = IntPtr.Zero;                                                  /* 保存AddItems函数的执行错误 */

            /* 执行结果信息 */
            try
            {
                Serverobj.AddGroup(name,
                                   0, dwRequestedUpdateRate,
                                   hClientGroup,
                                   hTimeBias.AddrOfPinnedObject(),
                                   hDeadband.AddrOfPinnedObject(),
                                   LOCALE_ID,
                                   out pSvrGroupHandle,
                                   out pRevUpdateRate,
                                   ref iidRequiredInterface,
                                   out MyobjGroup1);                                 //增加相应的组
                IOPCAsyncIO2Obj            = (IOPCAsyncIO2)MyobjGroup1;              //为组同步读写定义句柄
                IOPCGroupStateMgtObj       = (IOPCGroupStateMgt)MyobjGroup1;         //组管理对象
                pIConnectionPointContainer = (IConnectionPointContainer)MyobjGroup1; //增加特定组的异步调用连接

                Guid iid = typeof(IOPCDataCallback).GUID;                            //为所有的异步调用创建回调
                pIConnectionPointContainer.FindConnectionPoint(ref iid, out pIConnectionPoint);
                //为OPC server 的连接点与客户端接收点之间建立连接
                //  pIConnectionPoint.Advise(this, out dwCookie);
                tItemSvrHandleArray = new  int[1];
                OPCITEMDEF[] itemarray = new OPCITEMDEF[4];
                itemarray[0].szAccessPath        = "";       /* 访问路径"" */
                itemarray[0].szItemID            = itemname; /* OPC标签名称 */
                itemarray[0].hClient             = 1;
                tItemSvrHandleArray[0]           = 1;        /* 客户机的标签索引 */
                itemarray[0].dwBlobSize          = 0;
                itemarray[0].pBlob               = IntPtr.Zero;
                itemarray[0].vtRequestedDataType = 2;
                ItemSvrHandleArray               = new int[1, 1];
                ((IOPCItemMgt)MyobjGroup1).AddItems(1, itemarray, out pResults, out pErrors); //将标签加入到组中
                int[]  errors = new int[1];                                                   /* 每个标签的错误信息 */
                IntPtr pos    = pResults;
                Marshal.Copy(pErrors, errors, 0, 1);                                          /* pErrors->errors */
                for (int i = 0; i < 1; i++)                                                   /* 检查每个标签的error */
                {
                    if (errors[i] == 0)                                                       /* 如果无错误=0 */
                    {
                        if (i != 0)                                                           /* 如果不是第一个标签则指针移动一个OPCITEMRESULT */
                        {
                            pos = new IntPtr(pos.ToInt32() + Marshal.SizeOf(typeof(OPCITEMRESULT)));
                        }
                        OPCITEMRESULT result = (OPCITEMRESULT)Marshal.PtrToStructure(pos, typeof(OPCITEMRESULT)); /* IntPtr->OPCITEMRESULT */
                        ItemSvrHandleArray[0, 0] = result.hServer;                                                /* 保存该标签在服务器中的句柄,以后读写标签数值时要用到 */
                    }
                    else
                    {                                                                       /* 如果有错误(向服务器添加标签失败) */
                        connectedOK = false;                                                /* 连接失败 */
                        // String strError;
                        //  Serverobj.GetErrorString(errors[i], LOCALE_ID, out strError);   /* 获取错误信息 */
                        // OutputExceptionToDatabase(.......)                               /* 将异常信息输出到数据库 */
                        throw new Exception("添加标签:" + itemarray[i].szItemID + " 错误!" //+ strError
                                            );                                       /* 抛出异常 */
                    }
                }
            }
            catch (System.Exception error)
            {
                MessageBox.Show("group组添加失败失败\n" + error.Message);
            }
            finally
            {
                if (pResults != IntPtr.Zero)
                {
                    Marshal.FreeCoTaskMem(pResults);
                    pErrors = IntPtr.Zero;
                }
                if (pErrors != IntPtr.Zero)
                {
                    Marshal.FreeCoTaskMem(pErrors);
                    pErrors = IntPtr.Zero;
                }
            }
        }