Российский производитель и разработчик сертифицированного измерительного оборудования с 1987 года


LTR_GetListOfIPCrates И C#

Вы не вошли.

 Поиск | Регистрация | Вход 

15.05.2015 09:48:30
#1

Участник
Здесь с 13.05.2015
Сообщений: 9

LTR_GetListOfIPCrates И C#

Добрый день! Подскажите, пожалуйста, как правильно реализовать функцию LTR_GetListOfIPCrates.

//максимальное число крейтов
const uint max_entires = 16;
//IP-адрес сети (192.168.1.0)
uint ip_net = 0xC0A80100;
//маска подсети (255.255.255.0)
uint ip_mask = 0xFFFFFF00;
//количество найденных крейтов, соответствующих сетевым настройкам
uint entires_found;
//количество записей в массиве infoArray (возвращаемое процедурой)
uint entires_returned;
//массив для сохранения списка
_LTRNative.TIPCRATE_ENTRY[] cratesArray = new _LTRNative.TIPCRATE_ENTRY[max_entires];
//указатель на массив
IntPtr info_array = new IntPtr();
_LTRNative.LTR_GetListOfIPCrates(ref tLTR, max_entires, ip_net, ip_mask, out entires_found, out entires_returned, info_array);

Не многу понять, как связать cratesArray и info_array, пытался взять адрес cratesArray и передать его в указатель, но C# не позволяет такого сделать, поэтому просто проинициализировал как new IntPtr(), в результате запуска entires_found = 4, out entires_returned = 0 и info_array = 0.

15.05.2015 12:35:00
#2

Сотрудник "Л Кард"
Здесь с 17.04.2014
Сообщений: 1,338

Re: LTR_GetListOfIPCrates И C#

К сожалению в текущем варианте это не так просто.
По хорошему нужен класс-обертка, которая все необходимые преобразования делает внетри. Не знаю, может и дойдут до этого руки в этом месяце...
Сейчас же код для получения и вывода всех записей должен быть такой:

using System.Runtime.InteropServices;
using System.Net;

......

IntPtr ptr = IntPtr.Zero;
uint entries_found, entries_returned;
err = _LTRNative.LTR_GetListOfIPCrates(ref tltr, 0, 0, 0, out entries_found, out entries_returned, ptr);
if (err != _LTRNative.LTRERROR.OK)
{
    Console.WriteLine("Не получить количество записей. Ошибка {0}: {1}",
                   err, _LTRNative.GetErrorString(err));
} 
else
{
    if (entries_found == 0)
    {
        Console.WriteLine("Не найдено ни одной записи");
    }
    else
    {                        
        int size = Marshal.SizeOf(typeof(_LTRNative.TIPCRATE_ENTRY));
        ptr = Marshal.AllocHGlobal(size * (int)entries_found);
        err = _LTRNative.LTR_GetListOfIPCrates(ref tltr, entries_found, 0, 0, out entries_found, out entries_returned, ptr);
        if (err != _LTRNative.LTRERROR.OK)
        {
            Console.WriteLine("Не получить количество записей. Ошибка {0}: {1}",
                           err, _LTRNative.GetErrorString(err));
        }
        else
        {
            Console.WriteLine("Найдено {0} записей", entries_returned);
            _LTRNative.TIPCRATE_ENTRY[] entries = new _LTRNative.TIPCRATE_ENTRY[entries_returned];
            for (Int32 i = 0; i < entries_returned; i++)
            {
                IntPtr recptr = new IntPtr(ptr.ToInt32() + size * i);
                entries[i] = (_LTRNative.TIPCRATE_ENTRY)Marshal.PtrToStructure(recptr, typeof(_LTRNative.TIPCRATE_ENTRY));

                byte[] ip_bytes = BitConverter.GetBytes(entries[i].ip_addr);
                Array.Reverse(ip_bytes);
                Console.WriteLine("Запись {0}: {1}", i+1, new IPAddress(ip_bytes));
            }
        }
        Marshal.FreeHGlobal(ptr);
    }
}     
15.05.2015 13:10:07
#3

Участник
Здесь с 13.05.2015
Сообщений: 9

Re: LTR_GetListOfIPCrates И C#

Спасибо! Путем долгих поисков, проб и ошибок у меня вышло почти то же самое. Возможно кому-то пригодится.

public static unsafe void GetCratesStatus(_LTRNative.TLTR tLTR)
        {
            unsafe
            {
                //максимальное число крейтов
                const uint max_entires = 16;
                //IP-адрес сети (192.168.1.0)
                uint ip_net = 0xC0A80100;
                //маска подсети (255.255.255.0)
                uint ip_mask = 0xFFFFFF00;
                //количество найденных крейтов, соответствующих сетевым настройкам
                uint entires_found;
                //количество записей в массиве infoArray (возвращаемое процедурой)
                uint entires_returned;
                //выделение памяти
                int structSize = Marshal.SizeOf(typeof(_LTRNative.TIPCRATE_ENTRY)); 
                IntPtr info_array = Marshal.AllocHGlobal(structSize);
                Marshal.StructureToPtr(typeof(_LTRNative.TIPCRATE_ENTRY), info_array, true);
                //запрашиваем список крейтов
                _LTRNative.LTR_GetListOfIPCrates(ref tLTR, max_entires, ip_net, ip_mask, out entires_found, out entires_returned, info_array);
                //массив для сохранения списка 
                _LTRNative.TIPCRATE_ENTRY[] cratesArray = new _LTRNative.TIPCRATE_ENTRY[entires_found];
                //заполняем массив
                for (int index = 0; index < entires_found; index++)
                    cratesArray[index] = (index == 0) ? (_LTRNative.TIPCRATE_ENTRY)Marshal.PtrToStructure(info_array, typeof(_LTRNative.TIPCRATE_ENTRY))
                        : (_LTRNative.TIPCRATE_ENTRY)Marshal.PtrToStructure(info_array + structSize, typeof(_LTRNative.TIPCRATE_ENTRY));
                //освобождаем память
                Marshal.FreeHGlobal(info_array);
            }
        }