IOPCHDA_SyncRead pSyncIO = (IOPCHDA_SyncRead) pOPCHDAServer;
//Считываем выбранные временные диапазоны
DateTime fromTime = GetFromDateTime();
DateTime toTime = GetToDateTime();
tagOPCHDA_TIME opcFromTime = new tagOPCHDA_TIME();
opcFromTime.ftTime.dwLowDateTime = (uint)fromTime.ToFileTime();
opcFromTime.ftTime.dwHighDateTime =(uint)( fromTime.ToFileTime()
>> 32);
tagOPCHDA_TIME opcToTime = new tagOPCHDA_TIME();
opcToTime.ftTime.dwLowDateTime = (uint)toTime.ToFileTime();
opcToTime.ftTime.dwHighDateTime =(uint)(toTime.ToFileTime() >>
32);
IntPtr ipItemValues;
uint dwMaxValuesCount = 500; // Макс количество значений элемента
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);
// потом преобразуем два байта в одну двухбайтовую переменную
ushort usVt = (ushort)(vt[0] + vt[1] * 255);