public tagOPCITEMDEF GetItemDef() { tagOPCITEMDEF itemDef = new tagOPCITEMDEF(); itemDef.szItemID = ItemID; itemDef.szAccessPath = null; itemDef.bActive = Convert.ToInt32(Enabled); itemDef.hClient = 1; itemDef.vtRequestedDataType = (ushort)VarEnum.VT_EMPTY; itemDef.dwBlobSize = 0; itemDef.pBlob = IntPtr.Zero; return(itemDef); }
public OpcDaTagValue ReadTag(string tagId) { if (!IsConnected) { throw new InvalidOperationException("Невозможно прочитать тег. OPC сервер не подключен"); } var tag = Find(tagId); if (tag == null) { throw new InvalidOperationException("Невозможно прочитать тег. Тег не найден"); } // Запрашиваем интерфейс IOPServer IOPCServer pServer = (IOPCServer)_server; uint updateRate = 1000; // время опроса создаваемой группы int bActive = 1; // активность группы - активна uint hClientGroup = 1; // клиентский описатель группы object iFaceObj; // сюда вернем интерфейс к группе Guid riid = typeof(IOPCItemMgt).GUID; int TimeBias = 0; // Не используем смещения по времени float DeadBand = 0; // Не используем зону нечувствительности try { // Этот участок на данном этапе должен быть закомментирован. Его // необходимо будет использовать тогда, когда добавим асинхронную // операцию чтения по подписке //if (m_dwCookie != 0) //{ // m_pDataCallback.Unadvise(m_dwCookie); // m_dwCookie = 0; //} if (m_hGroup != 0) // Если группа была создана { pServer.RemoveGroup(m_hGroup, 1); // удалим её m_hGroup = 0; } pServer.AddGroup("MyGroup", bActive, updateRate, hClientGroup, ref TimeBias, ref DeadBand, 2, out m_hGroup, out updateRate, ref riid, out iFaceObj); IOPCItemMgt pItemMgt = (IOPCItemMgt)iFaceObj; // Создаём список элементов для добавления в группу, размером 1 элемент uint dwCount = 1; // Создаём описатель добавляемого элемента tagOPCITEMDEF pItems = new tagOPCITEMDEF(); pItems.szItemID = tag.TagId; pItems.szAccessPath = null; pItems.bActive = 1; pItems.hClient = 1; pItems.vtRequestedDataType = (ushort)VarEnum.VT_EMPTY; pItems.dwBlobSize = 0; pItems.pBlob = IntPtr.Zero; // В эти две переменные будут записаны массивы ошибок и // результатов выполнения IntPtr iptrErrors = IntPtr.Zero; IntPtr iptrResults = IntPtr.Zero; // Добавляем элемент данных в группу pItemMgt.AddItems(dwCount, pItems, out iptrResults, out iptrErrors); // Переносим результаты и ошибки зи неуправляемой памяти в управляемую tagOPCITEMRESULT pResults = (tagOPCITEMRESULT)Marshal.PtrToStructure(iptrResults, typeof(tagOPCITEMRESULT)); int[] hRes = new int[1]; Marshal.Copy(iptrResults, hRes, 0, 1); // Генерируем исключение в случае ошибки в HRESULT Marshal.ThrowExceptionForHR(hRes[0]); // Получаем интерфейс IOPCSyncIO для операций синхронного чтения IOPCSyncIO pSyncIO = (IOPCSyncIO)iFaceObj; // В эту переменную будут записаны результаты чтения IntPtr iptrItemState = IntPtr.Zero; iptrErrors = IntPtr.Zero; // Читаем данные из сервера pSyncIO.Read(tagOPCDATASOURCE.OPC_DS_DEVICE, 1, ref pResults.hServer, out iptrItemState, out iptrErrors); // Переносим результаты и ошибки из неуправляемой памяти в управляемую tagOPCITEMSTATE pItemState = (tagOPCITEMSTATE)Marshal.PtrToStructure(iptrItemState, typeof(tagOPCITEMSTATE)); Marshal.Copy(iptrErrors, hRes, 0, 1); // Генерируем исключение в случае ошибки в HRESULT Marshal.ThrowExceptionForHR(hRes[0]); return new OpcDaTagValue(tag.TagId, pResults.vtCanonicalDataType, pItemState.vDataValue, pItemState.ftTimeStamp, pItemState.wQuality); } catch (System.Exception ex) { //string msg; //Получаем HRESULT соответствующий сгененрированному исключению //int hRes = Marshal.GetHRForException(ex); //Запрашиваем у сервера текст ошибки, соответствующий текущему HRESULT //pServer.GetErrorString(hRes, 2, out msg); //Показываем сообщение ошибки //MessageBox.Show(msg, "Ошибка"); throw; } }
private void RegItemsInServer() { int dwCount = Items.Count(); Type type = typeof(tagOPCITEMDEF); IntPtr pItems = Marshal.AllocCoTaskMem((int)dwCount * Marshal.SizeOf(type)); m_dwReadCount = 0; indecies.Clear(); tagOPCITEMDEF[] itemDefs = new tagOPCITEMDEF[dwCount]; for (int i = 0; i < dwCount; i++) { OPCItem item = ((List <OPCItem>)Items)[i]; if (item.Enabled) { itemDefs[m_dwReadCount] = item.GetItemDef(); Marshal.StructureToPtr(itemDefs[m_dwReadCount], pItems + m_dwReadCount * Marshal.SizeOf(type), false); indecies.Add((uint)m_dwReadCount); m_dwReadCount++; } } IntPtr iptrErrors = IntPtr.Zero; IntPtr iptrResults = IntPtr.Zero; try { // Добавляем элемент данных в группу m_pItemMgt.AddItems((uint)m_dwReadCount, pItems, out iptrResults, out iptrErrors); } catch (ApplicationException ex) { Console.Out.WriteLine(ex.Message); } m_hItems = new uint[m_dwReadCount]; tagOPCITEMRESULT[] pResults = new tagOPCITEMRESULT[m_dwReadCount]; m_hRes = new int[dwCount]; Marshal.Copy(iptrErrors, m_hRes, 0, dwCount); try { for (int i = 0; i < m_dwReadCount; i++) { pResults[i] = (tagOPCITEMRESULT)Marshal.PtrToStructure(iptrResults + i * Marshal.SizeOf(typeof(tagOPCITEMRESULT)), typeof(tagOPCITEMRESULT)); m_hItems[i] = pResults[i].hServer; //Генерируем исключение в случае ошибки в HRESULT Marshal.ThrowExceptionForHR(m_hRes[i]); } } catch (System.Exception ex) { Console.Out.WriteLine(ex.Message); string msg; //Получаем HRESULT соответствующий сгененрированному исключению int hRes = Marshal.GetHRForException(ex); throw new ServerException(hRes); } Marshal.FreeCoTaskMem(pItems); Marshal.FreeCoTaskMem(iptrErrors); Marshal.FreeCoTaskMem(iptrResults); }