/// <summary> /// 读plc /// </summary> /// <returns></returns> public List <object> ReadPlc() { //Console.WriteLine("--------------开始读取plc数据!"); object[] redValue = new object[ItemServerHandle.Length]; IntPtr pItemValues = IntPtr.Zero; IntPtr pErrors = IntPtr.Zero; IOPCSyncIO2Obj.Read(OPCDATASOURCE.OPC_DS_DEVICE, 5, ItemServerHandle, out pItemValues, out pErrors); int[] errors = new int[ItemServerHandle.Length]; Marshal.Copy(pErrors, errors, 0, ItemServerHandle.Length); OPCITEMSTATE[] pItemState = new OPCITEMSTATE[ItemServerHandle.Length]; List <object> value = new List <object>(); for (int i = 0; i < ItemServerHandle.Length; i++) { if (errors[i] == 0) { pItemState[0] = (OPCITEMSTATE)Marshal.PtrToStructure(pItemValues, typeof(OPCITEMSTATE)); string ptrToStringUni = Marshal.PtrToStringUni(pItemValues); pItemValues = new IntPtr(pItemValues.ToInt64() + Marshal.SizeOf(typeof(OPCITEMSTATE))); OPCITEMSTATE opcitemstate = pItemState[0]; value.Add((object)pItemState[0].vDataValue); } } return(value); }
internal static ItemValue[] GetItemValues(ref IntPtr pInput, int count, bool deallocate) { ItemValue[] valueArray = null; if ((pInput != IntPtr.Zero) && (count > 0)) { valueArray = new ItemValue[count]; IntPtr ptr = pInput; for (int i = 0; i < count; i++) { OPCITEMSTATE opcitemstate = (OPCITEMSTATE)Marshal.PtrToStructure(ptr, typeof(OPCITEMSTATE)); valueArray[i] = new ItemValue(); valueArray[i].ClientHandle = opcitemstate.hClient; valueArray[i].Value = opcitemstate.vDataValue; valueArray[i].Quality = new Quality(opcitemstate.wQuality); valueArray[i].QualitySpecified = true; valueArray[i].Timestamp = OpcCom.Interop.GetFILETIME(Convert(opcitemstate.ftTimeStamp)); valueArray[i].TimestampSpecified = valueArray[i].Timestamp != DateTime.MinValue; if (deallocate) { Marshal.DestroyStructure(ptr, typeof(OPCITEMSTATE)); } ptr = (IntPtr)(ptr.ToInt32() + Marshal.SizeOf(typeof(OPCITEMSTATE))); } if (deallocate) { Marshal.FreeCoTaskMem(pInput); pInput = IntPtr.Zero; } } return(valueArray); }
public bool SyncRead(object[] values, int[] itemHandle) //同步读,读的结果存放在values中,读成功返回true,失败返回false { IntPtr pItemValues = IntPtr.Zero; IntPtr pErrors = IntPtr.Zero; bool isRead = false; try { if (values.Length != itemHandle.Length) { MessageBox.Show(string.Format("需要读出数据的个数与添加Item的数据说明长度不一致"), "读数据出错", MessageBoxButtons.OK, MessageBoxIcon.Error); return(false); } IOPCSyncObj.Read(OPCDATASOURCE.OPC_DS_DEVICE, itemHandle.Length, itemHandle, out pItemValues, out pErrors); int[] errors = new int[itemHandle.Length]; Marshal.Copy(pErrors, errors, 0, itemHandle.Length); OPCITEMSTATE pItemState = new OPCITEMSTATE(); for (int i = 0; i < itemHandle.Length; i++) { if (errors[i] == 0) { pItemState = (OPCITEMSTATE)Marshal.PtrToStructure(pItemValues, typeof(OPCITEMSTATE)); values[i] = pItemState.vDataValue.ToString(); //pItemState中还包含质量和时间等信息,目前只使用了读取的数据值 // values[i] = String.Format("{0}", pItemState.vDataValue); //pItemState中还包含质量和时间等信息,目前只使用了读取的数据值 pItemValues = new IntPtr(pItemValues.ToInt32() + Marshal.SizeOf(typeof(OPCITEMSTATE))); isRead = true; } else { String pstrError; //需不需要释放? ServerObj.GetErrorString(errors[i], LOCALE_ID, out pstrError); MessageBox.Show(string.Format("读出第{0}个数据时出错:{1}", i, pstrError), "读数据出错", MessageBoxButtons.OK, MessageBoxIcon.Error); isRead = false; break; } } } catch (System.Exception error) { isRead = false; MessageBox.Show(error.Message, "Result-Read Items", MessageBoxButtons.OK, MessageBoxIcon.Error); } finally { if (pItemValues != IntPtr.Zero) { Marshal.FreeCoTaskMem(pItemValues); pItemValues = IntPtr.Zero; } if (pErrors != IntPtr.Zero) { Marshal.FreeCoTaskMem(pErrors); pErrors = IntPtr.Zero; } } return(isRead); }
public bool SyncRead(object[] values, int[] itemHandle) { IntPtr zero = IntPtr.Zero; IntPtr ppErrors = IntPtr.Zero; bool flag = false; try { if (values.Length != itemHandle.Length) { MessageBox.Show(string.Format("需要读出数据的个数与添加Item的数据说明长度不一致", new object[0]), "读数据出错", MessageBoxButtons.OK, MessageBoxIcon.Hand); return(false); } this.IOPCSyncObj.Read(OPCDATASOURCE.OPC_DS_DEVICE, itemHandle.Length, itemHandle, out zero, out ppErrors); int[] destination = new int[itemHandle.Length]; Marshal.Copy(ppErrors, destination, 0, itemHandle.Length); OPCITEMSTATE opcitemstate = new OPCITEMSTATE(); for (int i = 0; i < itemHandle.Length; i++) { if (destination[i] == 0) { opcitemstate = (OPCITEMSTATE)Marshal.PtrToStructure(zero, typeof(OPCITEMSTATE)); values[i] = opcitemstate.vDataValue.ToString(); zero = new IntPtr(zero.ToInt32() + Marshal.SizeOf(typeof(OPCITEMSTATE))); flag = true; } else { string str; this.ServerObj.GetErrorString(destination[i], 0x804, out str); MessageBox.Show($"读出第{i}个数据时出错:{str}", "读数据出错", MessageBoxButtons.OK, MessageBoxIcon.Hand); return(false); } } return(flag); } catch (Exception exception) { flag = false; MessageBox.Show(exception.Message, "Result-Read Items", MessageBoxButtons.OK, MessageBoxIcon.Hand); } //finally //{ // if (zero != IntPtr.Zero) // { // Marshal.FreeCoTaskMem(zero); // zero = IntPtr.Zero; // } // if (ppErrors != IntPtr.Zero) // { // Marshal.FreeCoTaskMem(ppErrors); // ppErrors = IntPtr.Zero; // } //} return(flag); }
public object ReadD(int index) { // Access unmanaged COM memory IntPtr pItemValues = IntPtr.Zero; IntPtr pErrors = IntPtr.Zero; try { // Sync read from device pIOPCSyncIO.Read(OPCDATASOURCE.OPC_DS_DEVICE, 8, new Int32[] { ItemSvrHandleArray[index] }, out pItemValues, out pErrors); // Unmarshal the returned memory to get the item state out fom the ppItemValues // after checking errors int[] errors = new int[1]; Marshal.Copy(pErrors, errors, 0, 1); //if (errors[0] == 0) //{ OPCITEMSTATE pItemState = (OPCITEMSTATE)Marshal.PtrToStructure(pItemValues, typeof(OPCITEMSTATE)); // Free indirect variant element, other indirect elements are freed by Marshal.DestroyStructure(...) //DUMMY_VARIANT.VariantClear((IntPtr)((int)pItemValues + 0)); return(pItemState.vDataValue); //} //else //{ // return -1; //} // Free indirect structure elements Marshal.DestroyStructure(pItemValues, typeof(OPCITEMSTATE)); } catch (System.Exception error) { return(-1); } finally { // Free the unmanaged COM memory if (pItemValues != IntPtr.Zero) { Marshal.FreeCoTaskMem(pItemValues); pItemValues = IntPtr.Zero; } if (pErrors != IntPtr.Zero) { Marshal.FreeCoTaskMem(pErrors); pErrors = IntPtr.Zero; } } return(""); }
//同步读数据 private void Btn_Read_Click(object sender, EventArgs e) { IntPtr pItemValues = IntPtr.Zero; IntPtr pErrors = IntPtr.Zero; try { IOPCSyncIO20Obj.Read(OPCDATASOURCE.OPC_DS_DEVICE, 2, ItemServerHandle, out pItemValues, out pErrors); int[] errors = new int[2]; Marshal.Copy(pErrors, errors, 0, 2); OPCITEMSTATE[] pItemState = new OPCITEMSTATE[2]; if (errors[0] == 0) { pItemState[0] = (OPCITEMSTATE)Marshal.PtrToStructure(pItemValues, typeof(OPCITEMSTATE)); pItemValues = new IntPtr(pItemValues.ToInt32() + Marshal.SizeOf(typeof(OPCITEMSTATE))); Txt_R1Value.Text = String.Format("{0}", pItemState[0].vDataValue); Txt_R1Quality.Text = GetQuality(pItemState[0].wQuality); DateTime dt = ToDateTime(pItemState[0].ftTimeStamp); Txt_R1TimeStamp.Text = dt.ToString(); } if (errors[1] == 0) { pItemState[1] = (OPCITEMSTATE)Marshal.PtrToStructure(pItemValues, typeof(OPCITEMSTATE)); pItemValues = new IntPtr(pItemValues.ToInt32() + Marshal.SizeOf(typeof(OPCITEMSTATE))); Txt_R2Value.Text = String.Format("{0}", pItemState[1].vDataValue); Txt_R2Quality.Text = GetQuality(pItemState[1].wQuality); DateTime dt = ToDateTime(pItemState[1].ftTimeStamp); Txt_R2TimeStamp.Text = dt.ToString(); } } catch (System.Exception error) { MessageBox.Show(error.Message, "Result-Read Items", MessageBoxButtons.OK, MessageBoxIcon.Error); } finally { //free the memory if (pItemValues != IntPtr.Zero) { Marshal.FreeCoTaskMem(pItemValues); pItemValues = IntPtr.Zero; } if (pErrors != IntPtr.Zero) { Marshal.FreeCoTaskMem(pErrors); pErrors = IntPtr.Zero; } } }
internal Array Read(int serverHandler) { IntPtr zero = IntPtr.Zero; IntPtr ppItemValues = IntPtr.Zero; ((IOPCSyncIO)this.group).Read(OPCDATASOURCE.OPC_DS_DEVICE, 1, new int[] { serverHandler }, out ppItemValues, out zero); int[] destination = new int[1]; Marshal.Copy(zero, destination, 0, 1); if (destination[0] != 0) { throw new Exception("读OPC数据失败,原因:" + this.parent.GetLastError(destination[0])); } OPCITEMSTATE opcitemstate = (OPCITEMSTATE)Marshal.PtrToStructure(ppItemValues, typeof(OPCITEMSTATE)); if (opcitemstate.vDataValue is Array) { return((Array)opcitemstate.vDataValue); } return(new object[] { Convert.ToInt32(opcitemstate.vDataValue) }); }
/// <summary> /// 同步读 /// </summary> /// <param name="dataPointID"></param> /// <returns></returns> public object Read(int dataPointID) { IntPtr itemValues = IntPtr.Zero; IntPtr pErrors = IntPtr.Zero; try { OPCSyncIO.Read(OPCDATASOURCE.OPC_DS_DEVICE, 1, new int[] { OpcItems[dataPointID].ServerItemHandle }, out itemValues, out pErrors); int[] error = new int[1]; Marshal.Copy(pErrors, error, 0, error.Length); if (error[0] == 0) { OPCITEMSTATE itemState = (OPCITEMSTATE)Marshal.PtrToStructure(itemValues, typeof(OPCITEMSTATE)); return(itemState.vDataValue); } else { throw new ApplicationException($"数据点(ID:{dataPointID})同步读取失败。"); } } catch (Exception ex) { throw ex; } finally { if (itemValues != IntPtr.Zero) { Marshal.FreeCoTaskMem(itemValues); itemValues = IntPtr.Zero; } if (pErrors != IntPtr.Zero) { Marshal.FreeCoTaskMem(pErrors); pErrors = IntPtr.Zero; } } }
internal static IntPtr GetItemStates(ItemValueResult[] input) { IntPtr zero = IntPtr.Zero; if ((input != null) && (input.Length > 0)) { zero = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(OPCITEMSTATE)) * input.Length); IntPtr ptr = zero; for (int i = 0; i < input.Length; i++) { OPCITEMSTATE structure = new OPCITEMSTATE { hClient = System.Convert.ToInt32(input[i].ClientHandle), vDataValue = input[i].Value, wQuality = input[i].QualitySpecified ? input[i].Quality.GetCode() : ((short)0), ftTimeStamp = Convert(OpcCom.Interop.GetFILETIME(input[i].Timestamp)), wReserved = 0 }; Marshal.StructureToPtr(structure, ptr, false); ptr = (IntPtr)(ptr.ToInt32() + Marshal.SizeOf(typeof(OPCITEMSTATE))); } } return(zero); }
internal static IntPtr GetItemStates(ItemValueResult[] input) { IntPtr intPtr = IntPtr.Zero; if (input != null && input.Length > 0) { intPtr = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(OPCITEMSTATE)) * input.Length); IntPtr ptr = intPtr; for (int i = 0; i < input.Length; i++) { OPCITEMSTATE oPCITEMSTATE = default(OPCITEMSTATE); oPCITEMSTATE.hClient = System.Convert.ToInt32(input[i].ClientHandle); oPCITEMSTATE.vDataValue = input[i].Value; oPCITEMSTATE.wQuality = (short)(input[i].QualitySpecified ? input[i].Quality.GetCode() : 0); oPCITEMSTATE.ftTimeStamp = Convert(OpcCom.Interop.GetFILETIME(input[i].Timestamp)); oPCITEMSTATE.wReserved = 0; Marshal.StructureToPtr((object)oPCITEMSTATE, ptr, fDeleteOld: false); ptr = (IntPtr)(ptr.ToInt64() + Marshal.SizeOf(typeof(OPCITEMSTATE))); } } return(intPtr); }
/// <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); }
public override List <bool> UpdateBits() { // Access unmanaged COM memory IntPtr pItemValues = IntPtr.Zero; IntPtr pErrors = IntPtr.Zero; try { // Sync read from device pIOPCSyncIO.Read(OPCDATASOURCE.OPC_DS_DEVICE, 1, nItemSvrID, out pItemValues, out pErrors); // Unmarshal the returned memory to get the item state out fom the ppItemValues // after checking errors int[] errors = new int[1]; Marshal.Copy(pErrors, errors, 0, 1); if (errors[0] == 0) { OPCITEMSTATE pItemState = (OPCITEMSTATE)Marshal.PtrToStructure(pItemValues, typeof(OPCITEMSTATE)); RecodeUpdatetimes(); ushort b = ushort.Parse(pItemState.vDataValue.ToString()); bool[] rbits = b.ToBoolArray(); for (int j = 0; j < 16; j++) { bits.Add(rbits[j]); } // Free indirect variant element, other indirect elements are freed by Marshal.DestroyStructure(...) oleaut32.VariantClear(pItemValues + 0); return(bits); } else { string pstrError; pIOPCServer.GetErrorString(errors[0], LOCALE_ID, out pstrError); return(new List <bool>()); } // Free indirect structure elements Marshal.DestroyStructure(pItemValues, typeof(OPCITEMSTATE)); } catch (Exception error) { MessageBox.Show(error.Message, "Result - Read Items", MessageBoxButtons.OK, MessageBoxIcon.Error); } finally { // Free the unmanaged COM memory if (pItemValues != IntPtr.Zero) { Marshal.FreeCoTaskMem(pItemValues); pItemValues = IntPtr.Zero; } if (pErrors != IntPtr.Zero) { Marshal.FreeCoTaskMem(pErrors); pErrors = IntPtr.Zero; } } return(new List <bool>()); }
private void LoadOPC() { try { // OPC server variables. Type svrComponenttyp; OPCITEMDEF[] ItemDefArray; // Initialise Group properties int bActive = 0; int dwRequestedUpdateRate = 250; int hClientGroup = 0; int dwLCID = LOCALE_ID; int pRevUpdateRate; int TimeBias = 0; float deadband = 0; int vNo_OF_Tags = 1;//341; ItemDefArray = new OPCITEMDEF[vNo_OF_Tags]; // Access unmanaged COM memory GCHandle hTimeBias, hDeadband; hTimeBias = GCHandle.Alloc(TimeBias, GCHandleType.Pinned); hDeadband = GCHandle.Alloc(deadband, GCHandleType.Pinned); string[] itemIds = new string[vNo_OF_Tags]; string[] datas = new string[vNo_OF_Tags]; itemIds[S7_STR1_S_Send_STR1_Receive_TCM_HandshakingwithMIS_ID] = "S7:[S7 CONNECTION_1]MREAL100";//"S7:[STR1]S_Send.STR1.TataMis_Receive.TCM.L2_Cut_Length_S1";// // 1. Connect to Simens OPC DA local server. ( IP Address = 127.0.0.1 ) ( External Ip Address as = 192.168.1.145) Guid iidRequiredInterface = typeof(IOPCItemMgt).GUID; svrComponenttyp = System.Type.GetTypeFromProgID(SERVER_NAME); pIOPCServer = (IOPCServer)System.Activator.CreateInstance(svrComponenttyp); // MessageBox.Show("Connected"); //2. CC#3 add group function pIOPCServer.AddGroup(GROUP_NAME, bActive, dwRequestedUpdateRate, hClientGroup, hTimeBias.AddrOfPinnedObject(), hDeadband.AddrOfPinnedObject(), dwLCID, out nSvrGroupID, out pRevUpdateRate, ref iidRequiredInterface, out pobjGroup1); pIOPCSyncIO = (IOPCSyncIO)pobjGroup1; // nItemSvrID = new int[1]; // nItemSvrID[0] = 1;// result.hServer; //3.CC#3 add item function for (int i = 0; i < vNo_OF_Tags; i++) { ItemDefArray[i].szItemID = itemIds[i]; } ((IOPCItemMgt)pobjGroup1).AddItems(NUMBER_OF_TAGS, ItemDefArray, out pResults, out pErrors); for (int i = 0; i < vNo_OF_Tags; i++) { nItemSvrID[i] = i + 1; } //4. CC#3 Read item function IntPtr pItemValues = new IntPtr(); pIOPCSyncIO.Read(OPCDATASOURCE.OPC_DS_DEVICE, NUMBER_OF_TAGS, nItemSvrID, out pItemValues, out pErrors); IntPtr position = pItemValues; OPCITEMSTATE[] result = new OPCITEMSTATE[vNo_OF_Tags]; for (int i = 0; i < vNo_OF_Tags; i++) { result[i] = (OPCITEMSTATE)Marshal.PtrToStructure(position, typeof(OPCITEMSTATE)); double a = Convert.ToDouble(result[i].vDataValue.ToString()); MessageBox.Show("here " + result[i].vDataValue.ToString()); datas[i] = Convert.ToString(result[i].vDataValue); position = (IntPtr)(position.ToInt32() + Marshal.SizeOf(typeof(OPCITEMSTATE)));/*********************************/ } FuncFreeMemory(); unloadcomobjects(); // now as current data is available , proceed with the further functions. // tranfering the data to the previous variable of the TATA OPC Programe. output = new string[vNo_OF_Tags]; // TATA OPC Variable assigned to previous programe. for (int i = 0; i < vNo_OF_Tags; i++) { output[i] = datas[i]; } // Handle Strand Communication Faliure. // Added on 12th August 2011 - for (int i = 0; i < vNo_OF_Tags; i++) { if ((output[i] == null) || (output[i] == "")) { output[i] = Convert.ToString(0); string vDate = DateTime.Now.Day + "-" + DateTime.Now.Month + "-" + DateTime.Now.Year; string vDate1 = DateTime.Now.Day + "-" + DateTime.Now.Month + "-" + DateTime.Now.Year + "_" + DateTime.Now.Hour + "_" + DateTime.Now.Minute + "_" + DateTime.Now.Second; objWriteFile = new StreamWriter(FilePath + "CC3_ACS_Errors_" + vDate + ".txt", true); objWriteFile.WriteLine("Communicaiton Error:-" + itemIds[i] + "\tDate :-\t" + vDate1); // Log The Tag and associated PLC For the Communication Errors objWriteFile.Close(); } } for (int i = 0; i < vNo_OF_Tags; i++) { datas[i] = null; } // disconnecting Server. Marshal.ReleaseComObject(pIOPCServer); pIOPCServer = null; } catch (Exception ex) { //MessageBox.Show(ex.Message); string vDate = DateTime.Now.Day + "-" + DateTime.Now.Month + "-" + DateTime.Now.Year; //objWriteFile = new StreamWriter(FilePath + "CC3_ACS_Errors_" + vDate + ".txt", true); //objWriteFile.WriteLine("Load OPC Error:-" + ex.Message + "\tDate :-\t" + vDate); //objWriteFile.Close(); } }
/// <summary> /// Read the list of items. /// </summary> /// <param name="itemIds">Items to read.</param> /// <param name="values">The values that were read.</param> /// <param name="pErrors">Individual error code for each item</param> /// <returns>Returns true if read succeeded for all items. Otherwise returns false.</returns> public bool Read(StringCollection itemIds, out object[] values, out int[] pErrors) { bool bResult = true; values = new object[itemIds.Count]; pErrors = new int[itemIds.Count]; if (!m_connected) { throw new InvalidOperationException("Not connected to OPC-Server!"); } int[] serverHandles; try { bResult = GetServerHandles(itemIds, out serverHandles, out pErrors); } catch (Exception e) { throw e; } // build in parameters to read int[] serverHandlesToRead; ArrayList indexesToRead = new ArrayList(); ArrayList indexesNotToRead = new ArrayList(); ArrayList handlesTmp = new ArrayList(); // check each handle for (int i = 0; i < itemIds.Count; i++) { if (pErrors[i] == 0) { handlesTmp.Add(serverHandles[i]); indexesToRead.Add(i); } else { indexesNotToRead.Add(i); } } serverHandlesToRead = (int[])handlesTmp.ToArray(typeof(int)); if (serverHandlesToRead.Length == 0) { return(false); } IntPtr pItemValues; IntPtr ppErrors; try { m_syncIO.Read( OPCDATASOURCE.OPC_DS_DEVICE, // DataSource is Device or Cache serverHandlesToRead.Length, // Number of items to read serverHandlesToRead, // out pItemValues, // out ppErrors); // } catch (Exception e) { throw e; } if (pItemValues == IntPtr.Zero) { throw new Exception("Read failed. No Results."); } if (ppErrors == IntPtr.Zero) { throw new Exception("Read failed. No ErrorCodes returned."); } int[] errorsTmp = Helper.GetInt32s(ref ppErrors, serverHandlesToRead.Length, true); int indexTmp = 0; IntPtr pos = pItemValues; // Fill result of items that were read foreach (int index in indexesToRead) { // set error code pErrors[index] = errorsTmp[indexTmp]; OPCITEMSTATE itemState = (OpcRcw.Da.OPCITEMSTATE)Marshal.PtrToStructure(pos, typeof(OPCITEMSTATE)); Marshal.DestroyStructure(pos, typeof(OpcRcw.Da.OPCITEMSTATE)); pos = (IntPtr)(pos.ToInt64() + Marshal.SizeOf(typeof(OPCITEMSTATE))); // set value values[index] = itemState.vDataValue; indexTmp++; } Marshal.FreeCoTaskMem(pItemValues); pItemValues = IntPtr.Zero; // Fill results of items that were not read. foreach (int index in indexesNotToRead) { // error code was alread set above - just initialize value element values[index] = null; } return(bResult); }