예제 #1
0
        /// <summary>Reads opc-items via an synchronous read</summary>
        /// <param name="OPCDataSrc">determines the source, the data have to be read (cache or device)</param>
        /// <param name="itemServerHandles">the serverhandles of the opc-items to be read</param>
        /// <param name="theGroup">the group in which the opc-items are hosted</param>
        /// <returns> itemstates, returned form the opc-server </returns>
        public OPCITEMSTATE[] readSync(OpcRcw.Da.OPCDATASOURCE OPCDataSrc,
                                       int[] itemServerHandles, out int[] errors)
        {
            if (m_disposed)
            {
                throw new NullReferenceException("This object has been disposed!");
            }

            IntPtr pItemStates = IntPtr.Zero;
            IntPtr pErrors     = IntPtr.Zero;
            int    NumItems    = itemServerHandles.Length;

            OPCITEMSTATE[] result = new OPCITEMSTATE[NumItems];

            string ErrorStr = "";

            try
            {
                // Usually reading from CACHE is more efficient
                // AND the underlying device has to do less communication work.
                // BUT, you must have an active ITEM and GROUP, so that the opc server
                // will update the data by itself; otherwise you'll get quality OUT_OF_SERVICE
                m_OPCSyncIO.Read(OPCDataSrc,                            //OPCDATASOURCE.OPC_DS_DEVICE or OPCDATASOURCE.OPC_DS_CACHE,
                                 NumItems,
                                 itemServerHandles,
                                 out pItemStates,
                                 out pErrors);

                if (pItemStates == IntPtr.Zero)
                {
                    throw new ArgumentNullException("EXT_OPC_RDSYNC_ITEMSTATES");
                }
                if (pErrors == IntPtr.Zero)
                {
                    throw new ArgumentNullException("EXT_OPC_RDSYNC_ERRORS");
                }

                //Evaluate return ErrorCodes to exclude possible Errors
                errors = new int[NumItems];
                Marshal.Copy(pErrors, errors, 0, NumItems);

                IntPtr pos = pItemStates;

                // Now get the read values and check errors
                for (int dwCount = 0; dwCount < NumItems; dwCount++)
                {
                    result[dwCount] = (OPCITEMSTATE)Marshal.PtrToStructure(pos, typeof(OPCITEMSTATE));

                    if (errors[dwCount] != 0)
                    {
                        m_OPCServer.GetErrorString(errors[dwCount], m_LocaleID, out ErrorStr);
                        System.Diagnostics.Debug.WriteLine(ErrorStr);
                    }

                    pos = (IntPtr)(pos.ToInt32() + Marshal.SizeOf(typeof(OPCITEMSTATE)));
                }

                if (ErrorStr != "")
                {
                    throw new Exception(ErrorStr);
                }

                // Free allocated COM-ressouces
                Marshal.FreeCoTaskMem(pItemStates);
                Marshal.FreeCoTaskMem(pErrors);
            }
            catch (Exception)
            {
                // Free allocated COM-ressouces
                Marshal.FreeCoTaskMem(pItemStates);
                Marshal.FreeCoTaskMem(pErrors);

                // just forward it
                throw;
            }
            return(result);
        }
예제 #2
0
        /*------------------------------------------------------
        *  Execute SyncRead
        *
        *  (ret)   True    OK
        *               False   NG
        *  ------------------------------------------------------*/
        public bool SyncRead(OpcRcw.Da.OPCDATASOURCE DataSource, int[] ServerHd, object[] Values, OpcRcw.Da.FILETIME[] TimeStamps, short[] Qualities)
        {
            int         iItemCount = ServerHd.Length;
            IOPCSyncIO  OPCSyncIO;
            IOPCSyncIO2 OPCSyncIO2;
            IntPtr      ppItemVal;
            IntPtr      ppErrors;
            IntPtr      posItem;

            int[]        Errors = new int[iItemCount];
            OPCITEMSTATE ItemState;
            int          i;

            try
            {
                switch (m_OpcdaVer)
                {
                case DEF_OPCDA.VER_30:
                    OPCSyncIO2 = (IOPCSyncIO2)m_OPCGroup2;
                    OPCSyncIO2.Read(DataSource, iItemCount, ServerHd, out ppItemVal, out ppErrors);
                    Marshal.Copy(ppErrors, Errors, 0, iItemCount);
                    posItem = ppItemVal;
                    for (i = 0; i < iItemCount; i++)
                    {
                        ItemState = (OPCITEMSTATE)Marshal.PtrToStructure(posItem, typeof(OPCITEMSTATE));
                        if (Errors[i] == 0)
                        {
                            Values[i]     = ItemState.vDataValue;
                            TimeStamps[i] = ItemState.ftTimeStamp;
                            Qualities[i]  = ItemState.wQuality;
                        }
                        Marshal.DestroyStructure(posItem, typeof(OPCITEMSTATE));                                                // 05/02/08 Release memory
                        //posItem = new IntPtr(posItem.ToInt32() + Marshal.SizeOf(typeof(OPCITEMSTATE)));		// 1.0.0.5 10/06/21 Kishimoto Fixed for Memory Leak
                        posItem = (IntPtr)(posItem.ToInt32() + Marshal.SizeOf(typeof(OpcRcw.Da.OPCITEMSTATE)));                 // 1.0.0.5 10/06/21 Kishimoto Fixed for Memory Leak
                    }
                    Marshal.FreeCoTaskMem(ppItemVal);
                    Marshal.FreeCoTaskMem(ppErrors);
                    break;

                case DEF_OPCDA.VER_10:
                case DEF_OPCDA.VER_20:
                default:
                    OPCSyncIO = (IOPCSyncIO)m_OPCGroup;
                    OPCSyncIO.Read(DataSource, iItemCount, ServerHd, out ppItemVal, out ppErrors);
                    Marshal.Copy(ppErrors, Errors, 0, iItemCount);
                    posItem = ppItemVal;
                    for (i = 0; i < iItemCount; i++)
                    {
                        ItemState = (OPCITEMSTATE)Marshal.PtrToStructure(posItem, typeof(OPCITEMSTATE));
                        if (Errors[i] == 0)
                        {
                            Values[i]     = ItemState.vDataValue;
                            TimeStamps[i] = ItemState.ftTimeStamp;
                            Qualities[i]  = ItemState.wQuality;
                        }
                        Marshal.DestroyStructure(posItem, typeof(OPCITEMSTATE));                                                // 05/02/08 Release memory
                        //posItem = new IntPtr(posItem.ToInt32() + Marshal.SizeOf(typeof(OPCITEMSTATE)));		// 1.0.0.5 10/06/21 Kishimoto Fixed for Memory Leak
                        posItem = (IntPtr)(posItem.ToInt32() + Marshal.SizeOf(typeof(OpcRcw.Da.OPCITEMSTATE)));                 // 1.0.0.5 10/06/21 Kishimoto Fixed for Memory Leak
                    }
                    Marshal.FreeCoTaskMem(ppItemVal);
                    Marshal.FreeCoTaskMem(ppErrors);
                    break;
                }
            }
            catch (Exception exc)
            {
                MessageBox.Show(exc.ToString(), "SyncRead");
                return(false);
            }
//			erase Errors
            System.GC.Collect();              //04/12/29 Revised Memory Leak
            return(true);
        }