есть функция
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 данные к массиву структур?
Здравствуйте, x64, Вы писали:
x64>Необходимую информацию можно найти на pinvoke.net. Вот эти сэмплы помогут:
x64>GetTokenInformation
x64>WTSQuerySessionInformation
x64>NtQueryInformationProcess
x64>NtCreateFile
Первый сэмпл вообще показывает как получить структуру из intptr.
Второй показывает только маршалирование intptr в int32.
Третий и четвертый — без примеров.
потому сэмплы вообще ниочем.
А мне необходимо получить
массив из intptr
Благо зарубежные коллеги в IRC'е помогли. Опробую их совет — выложу сюда.
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;
}