private void grouop_DataChanged(object sender, DataChangeEventArgs e) { foreach (OPCItemState sta in e.sts) { OPCItem item = this.group.Items.GetItemByClientHandler(sta.HandleClient); foreach (ItemValue iv in values) { if (iv.id == item.ID) { iv.value = sta; break; } } } foreach (ItemValue iv in values) { if (iv.value == null) { readed = false; return; } } readed = true; }
public OPCItemState[] Read(int[] arrHSrv) { OPCItemState[] arrStat; arrStat = null; int count = arrHSrv.Length; IntPtr ptrStat; IntPtr ptrErr; int hresult = ifSync.Read(OPCDATASOURCE.OPC_DS_DEVICE, count, arrHSrv, out ptrStat, out ptrErr); if (HRESULTS.Failed(hresult)) { #region 新建组读取 values = new List <ItemValue>(); readed = false; OPC.Data.OpcGroup grouop = new OpcGroup("wef2", true, 500, 500, 0); this.group = grouop; this.Server.OpcGroups.Add(grouop); grouop.DataChanged += new DataChangeEventHandler(grouop_DataChanged); int index = 0; foreach (int hid in arrHSrv) { OPCItem item = this.Items.GetItemByServerHandler(hid); values.Add(new ItemValue(item.ID, null)); } foreach (int hid in arrHSrv) { OPCItem item = this.Items.GetItemByServerHandler(hid); OPCItem newItem = new OPCItem(item.ID, index); grouop.Items.Add(newItem); index++; } while (true) { if (readed) { OPCItemState[] states = new OPCItemState[arrHSrv.Length]; for (int i = 0; i < states.Length; i++) { states[i] = values[i].value; } this.group = null; grouop.Items.Clear(); this.Server.OpcGroups.Remove(grouop); return(states); } Thread.Sleep(20); } #endregion if (HRESULTS.Failed(hresult)) { throw (new Exception("读取Item值出错,public OPCItemState[] Read(int[] arrHSrv)函数ifSync.Read(OPCDATASOURCE.OPC_DS_CACHE, count, arrHSrv, out ptrStat, out ptrErr)语句")); } } int runErr = (int)ptrErr; int runStat = (int)ptrStat; if ((runErr == 0) || (runStat == 0)) { Marshal.ThrowExceptionForHR(HRESULTS.E_ABORT); } arrStat = new OPCItemState[count]; for (int i = 0; i < count; i++) { // WORKAROUND !!! OPCItemState item = new OPCItemState(); arrStat[i] = item; item.Error = Marshal.ReadInt32((IntPtr)runErr); runErr += 4; item.HandleClient = Marshal.ReadInt32((IntPtr)runStat); if (HRESULTS.Succeeded(item.Error)) { short vt = Marshal.ReadInt16((IntPtr)(runStat + 16)); if (vt == (short)VarEnum.VT_ERROR) { item.Error = Marshal.ReadInt32((IntPtr)(runStat + 24)); } try { item.TimeStamp = DateTime.FromFileTime(Marshal.ReadInt64((IntPtr)(runStat + 4))); } catch { } try { item.QualityString = OpcGroup.QualityToString(Marshal.ReadInt16((IntPtr)(runStat + 12))); } catch { } item.DataValue = Marshal.GetObjectForNativeVariant((IntPtr)(runStat + 16)); DUMMY_VARIANT.VariantClear((IntPtr)(runStat + 16)); } else { item.DataValue = null; } runStat += 32; } Marshal.FreeCoTaskMem(ptrStat); Marshal.FreeCoTaskMem(ptrErr); return(arrStat); //if (hresult == HRESULTS.S_OK) //{ // return arrStat; //} //else //{ // return null; //} }
// ----------------------------------------------------------------------------------- public bool ValidateItems(OPCItemDef[] arrDef, bool blobUpd, out OPCItem[] arrRes) { arrRes = null; bool hasblobs = false; int count = arrDef.Length; IntPtr ptrDef = Marshal.AllocCoTaskMem(count * sizeOPCITEMDEF); int runDef = (int)ptrDef; OPCITEMDEFintern idf = new OPCITEMDEFintern(); idf.wReserved = 0; foreach (OPCItemDef d in arrDef) { idf.szAccessPath = d.AccessPath; idf.szItemID = d.ItemID; idf.bActive = d.Active; idf.hClient = d.HandleClient; idf.vtRequestedDataType = (short)d.RequestedDataType; idf.dwBlobSize = 0; idf.pBlob = IntPtr.Zero; if (d.Blob != null) { idf.dwBlobSize = d.Blob.Length; if (idf.dwBlobSize > 0) { hasblobs = true; idf.pBlob = Marshal.AllocCoTaskMem(idf.dwBlobSize); Marshal.Copy(d.Blob, 0, idf.pBlob, idf.dwBlobSize); } } Marshal.StructureToPtr(idf, (IntPtr)runDef, false); runDef += sizeOPCITEMDEF; } IntPtr ptrRes; IntPtr ptrErr; int hresult = ifItems.ValidateItems(count, ptrDef, blobUpd, out ptrRes, out ptrErr); runDef = (int)ptrDef; if (hasblobs) { for (int i = 0; i < count; i++) { IntPtr blob = (IntPtr)Marshal.ReadInt32((IntPtr)(runDef + 20)); if (blob != IntPtr.Zero) { Marshal.FreeCoTaskMem(blob); } Marshal.DestroyStructure((IntPtr)runDef, typeOPCITEMDEF); runDef += sizeOPCITEMDEF; } } else { for (int i = 0; i < count; i++) { Marshal.DestroyStructure((IntPtr)runDef, typeOPCITEMDEF); runDef += sizeOPCITEMDEF; } } Marshal.FreeCoTaskMem(ptrDef); if (HRESULTS.Failed(hresult)) { Marshal.ThrowExceptionForHR(hresult); } int runRes = (int)ptrRes; int runErr = (int)ptrErr; if ((runRes == 0) || (runErr == 0)) { Marshal.ThrowExceptionForHR(HRESULTS.E_ABORT); } arrRes = new OPCItem[count]; for (int i = 0; i < count; i++) { arrRes[i] = new OPCItem(); arrRes[i].Error = Marshal.ReadInt32((IntPtr)runErr); if (HRESULTS.Failed(arrRes[i].Error)) { continue; } arrRes[i].HandleServer = Marshal.ReadInt32((IntPtr)runRes); arrRes[i].DataType = Helper.VT2TypeCode((VarEnum)(int)Marshal.ReadInt16((IntPtr)(runRes + 4))); arrRes[i].AccessRights = (OPCACCESSRIGHTS)Marshal.ReadInt32((IntPtr)(runRes + 8)); int ptrblob = Marshal.ReadInt32((IntPtr)(runRes + 16)); if ((ptrblob != 0)) { int blobsize = Marshal.ReadInt32((IntPtr)(runRes + 12)); if (blobsize > 0) { arrRes[i].Blob = new byte[blobsize]; Marshal.Copy((IntPtr)ptrblob, arrRes[i].Blob, 0, blobsize); } Marshal.FreeCoTaskMem((IntPtr)ptrblob); } runRes += sizeOPCITEMRESULT; runErr += 4; } Marshal.FreeCoTaskMem(ptrRes); Marshal.FreeCoTaskMem(ptrErr); return(hresult == HRESULTS.S_OK); }
// ------------------------ IOPCItemMgt --------------- internal void AddItems(OPCItem[] items) { OPCItemDef[] arrDef = new OPCItemDef[items.Length]; for (int i = 0; i < items.Length; i++) { arrDef[i] = new OPCItemDef(items[i].ID, items[i].HandleClient); } bool hasblobs = false; int count = arrDef.Length; IntPtr ptrDef = Marshal.AllocCoTaskMem(count * sizeOPCITEMDEF); int runDef = (int)ptrDef; OPCITEMDEFintern idf = new OPCITEMDEFintern(); idf.wReserved = 0; foreach (OPCItemDef d in arrDef) { idf.szAccessPath = d.AccessPath; idf.szItemID = d.ItemID; idf.bActive = d.Active; idf.hClient = d.HandleClient; idf.vtRequestedDataType = (short)d.RequestedDataType; idf.dwBlobSize = 0; idf.pBlob = IntPtr.Zero; if (d.Blob != null) { idf.dwBlobSize = d.Blob.Length; if (idf.dwBlobSize > 0) { hasblobs = true; idf.pBlob = Marshal.AllocCoTaskMem(idf.dwBlobSize); Marshal.Copy(d.Blob, 0, idf.pBlob, idf.dwBlobSize); } } Marshal.StructureToPtr(idf, (IntPtr)runDef, false); runDef += sizeOPCITEMDEF; } IntPtr ptrRes; IntPtr ptrErr; int hresult = ifItems.AddItems(count, ptrDef, out ptrRes, out ptrErr); runDef = (int)ptrDef; if (hasblobs) { for (int i = 0; i < count; i++) { IntPtr blob = (IntPtr)Marshal.ReadInt32((IntPtr)(runDef + 20)); if (blob != IntPtr.Zero) { Marshal.FreeCoTaskMem(blob); } Marshal.DestroyStructure((IntPtr)runDef, typeOPCITEMDEF); runDef += sizeOPCITEMDEF; } } else { for (int i = 0; i < count; i++) { Marshal.DestroyStructure((IntPtr)runDef, typeOPCITEMDEF); runDef += sizeOPCITEMDEF; } } Marshal.FreeCoTaskMem(ptrDef); if (HRESULTS.Failed(hresult)) { Marshal.ThrowExceptionForHR(hresult); } int runRes = (int)ptrRes; int runErr = (int)ptrErr; if ((runRes == 0) || (runErr == 0)) { Marshal.ThrowExceptionForHR(HRESULTS.E_ABORT); } for (int i = 0; i < count; i++) { OPCItem item = items[i]; item.Group = this; item.Error = Marshal.ReadInt32((IntPtr)runErr); if (HRESULTS.Failed(item.Error)) { continue; } item.HandleServer = Marshal.ReadInt32((IntPtr)runRes); item.DataType = Helper.VT2TypeCode((VarEnum)(int)Marshal.ReadInt16((IntPtr)(runRes + 4))); item.AccessRights = (OPCACCESSRIGHTS)Marshal.ReadInt32((IntPtr)(runRes + 8)); int ptrblob = Marshal.ReadInt32((IntPtr)(runRes + 16)); if ((ptrblob != 0)) { int blobsize = Marshal.ReadInt32((IntPtr)(runRes + 12)); if (blobsize > 0) { item.Blob = new byte[blobsize]; Marshal.Copy((IntPtr)ptrblob, item.Blob, 0, blobsize); } Marshal.FreeCoTaskMem((IntPtr)ptrblob); } runRes += sizeOPCITEMRESULT; runErr += 4; } Marshal.FreeCoTaskMem(ptrRes); Marshal.FreeCoTaskMem(ptrErr); if (hresult == HRESULTS.S_OK) { return; } else { string itemstring = ""; foreach (OPCItem item in items) { itemstring += item.ID + ","; } try { Exception excep = Marshal.GetExceptionForHR(hresult); throw (new Exception(excep.Message + " 添加OPCItem时出错" + itemstring)); } catch { throw (new Exception("HRESULTS:" + hresult + " 添加OPCItem时出错" + itemstring)); } } }