IntPtr to Stuctures array
От: Аноним  
Дата: 29.08.09 17:36
Оценка:
есть функция

NTSTATUS WINAPI Bla-Bla-Bla(  
__inout    PVOID SystemInformation,
__in       ULONG SystemInformationLength,
__out_opt  PULONG ReturnLength );


первый параметр — буфер для получения информации переменной длины, второй — длина буфера в байтах.
В буфер попадает массив из структур.
необходимо ее использовать в C#, потому привел ее к надлежащему виду (поправьте если не так):

[DllImport("Bla.dll", EntryPoint="Bla-Bla-Bla")]
 static extern long Super(
        ref IntPtr SystemInformation,
        ulong SystemInformationLength,
        out long ReturnLength);


Пример вызова:
IntPtr ptr = Marshal.AllocHGlobal(elementCount * Marshal.SizeOf(typeof(SystemInfoStructure)));
long formal;
Super(ref ptr, (ulong)(elementCount * Marshal.SizeOf(typeof(SystemInfoStructure))), out formal);

Каким образом можно привести полученные в ptr данные к массиву структур?
Re: IntPtr to Stuctures array
От: x64 Россия  
Дата: 30.08.09 01:38
Оценка:
Необходимую информацию можно найти на pinvoke.net. Вот эти сэмплы помогут:

GetTokenInformation
WTSQuerySessionInformation
NtQueryInformationProcess
NtCreateFile
Re[2]: IntPtr to Stuctures array
От: CL0NE Украина  
Дата: 30.08.09 11:41
Оценка:
Здравствуйте, x64, Вы писали:

x64>Необходимую информацию можно найти на pinvoke.net. Вот эти сэмплы помогут:


x64>GetTokenInformation

x64>WTSQuerySessionInformation
x64>NtQueryInformationProcess
x64>NtCreateFile

Первый сэмпл вообще показывает как получить структуру из intptr.
Второй показывает только маршалирование intptr в int32.
Третий и четвертый — без примеров.
потому сэмплы вообще ниочем.


А мне необходимо получить массив из intptr

Благо зарубежные коллеги в IRC'е помогли. Опробую их совет — выложу сюда.
Re: IntPtr to Stuctures array
От: CL0NE Украина  
Дата: 01.09.09 17:50
Оценка:
Microsoft Connect, 2005-й год — решение данной проблемы. Для тех, кто не любит ходить по ссылкам — скопипастяю код:

/// <summary>
/// Converts an unmanaged array to a managed <see cref="Array"/>.
/// </summary>
/// <param name="structureType">The .NET <see cref="Type"/> that best represents
/// the type of element stored in the unmanaged array. Only structs are supported.</param>
/// <param name="arrayPtr">The address of the unmanaged array.</param>
/// <param name="length">The number of elements in the unmanaged array.</param>
/// <returns>An <see cref="Array"/> of <paramref name="structureType"/> where each
/// index in the managed array contains an element copied from the unmanaged array.</returns>
public static Array PtrToArray(
Type structureType,
IntPtr arrayPtr,
int length
)
{
if(structureType == null)
throw new ArgumentNullException("structureType");
if(!structureType.IsValueType)
throw new ArgumentException("Only struct types are supported.", "structureType");
if(length < 0)
throw new ArgumentOutOfRangeException("length", length, "length must be equal to or greater than zero.");
if(arrayPtr == IntPtr.Zero)
return null;
int size = Marshal.SizeOf(structureType);
Array array = Array.CreateInstance(structureType, length);
for(int i=0; i < length; i++)
{
IntPtr offset = new IntPtr((long) arrayPtr + (size * i));
object value = Marshal.PtrToStructure(offset, structureType);
array.SetValue(value, i);
}
return array;
}
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.