pOPCHDAServer.GetItemHandles(dwCount, ref itemID, ref
phClient, out hItems, out pErrors);
int[] iItems = new int[1];
Marshal.Copy(hItems, iItems, 0, 1);
Marshal.FreeCoTaskMem(pErrors);
uint uiItems = (uint)iItems[0];
IOPCHDA_SyncRead pSyncIO = (IOPCHDA_SyncRead)pOPCHDAServer;
tagOPCHDA_TIME opcFromTime = new tagOPCHDA_TIME();
opcFromTime.bString = 1;
opcFromTime.szTime = "NOW-10M";
tagOPCHDA_TIME opcToTime = new tagOPCHDA_TIME();
opcToTime.bString = 1;
opcToTime.szTime = "NOW";
IntPtr ipItemValues;
uint dwMaxValuesCount = 2500; // Макс количество значений
элемента
int bBounds = 0;
//Синхронное чтение данных
pSyncIO.ReadRaw(ref opcFromTime, ref opcToTime,
dwMaxValuesCount, bBounds, dwCount, ref uiItems, out ipItemValues,
out pErrors);
//---Теперь начинаем разбираться с типами COM и .NET --------
//-----Получаем структуру tagOPCHDA_ITEM
tagOPCHDA_ITEM pItemValues =
(tagOPCHDA_ITEM)Marshal.PtrToStructure(ipItemValues,
typeof(tagOPCHDA_ITEM));
Marshal.FreeCoTaskMem(pErrors);
Marshal.FreeCoTaskMem(ipItemValues);
if (0 == pItemValues.dwCount) return;
// Выделяем массив качеств, считанных значений элемента
int[] iQuality = new int[pItemValues.dwCount];
Marshal.Copy(pItemValues.pdwQualities, iQuality, 0,
(int)(pItemValues.dwCount));
//Выделяем тип данных элемента из массива Variant
//pItemValues.pvDataValues, который в .NET представлен как IntPtr
//вначале выделяем по два байта (размер dwQuality) из
//pItemValues.pvDataValues
byte[] vt = new byte[2];
Marshal.Copy(pItemValues.pvDataValues, vt, 0, 2);
// потом преобразуем два байта в одну двухбайтовую переменную