Получение массива структуры из IntPtr - PullRequest
10 голосов
/ 19 июля 2011

У меня есть какая-то структура, подобная этой

struct MyStruct
{
    public int field1;
    public int field2;
    public int field3;
}

, и у меня есть указатель на массив этой структуры.Итак, мне нужно получить массив из этого указателя.Я пытался использовать Marshal.PtrToStructure, но у меня была ошибка чтения из памяти.Это мой метод:

public MyStruct[] GetArrayOfStruct(IntPtr pointerToStruct, int length)
{
    var sizeInBytes = Marshal.SizeOf(typeof(TCnt));
    MyStruct[] output = new MyStruct[length];

    for (int i = 0; i < length; i++)
    {
        IntPtr p = new IntPtr((pointerToStruct.ToInt32() + i * sizeInBytes));

        output[i] = (MyStruct)System.Runtime.InteropServices.Marshal.PtrToStructure(p, typeof(MyStruct));
    }

    return output;
}

Итак, что я делаю не так?

Ответы [ 3 ]

4 голосов
/ 19 июля 2011

Две проблемы.Вы используете TCnt вместо MyStruct в вызове Marshal.SizeOf ().Ваша арифметика IntPtr не может работать на 64-битной машине, вы должны использовать IntPtr.ToInt64 () или приводить к (long).

Конечно, тоже возможно получить неправильный IntPtr или длину.Используйте Debug + Windows + Memory + Memory 1 и поместите «pointerToStruct» в поле адреса для базовой проверки.

3 голосов
/ 02 ноября 2016

Эта функция работала для меня, предполагая, что размер структуры фиксирован :

public static void MarshalUnmananagedArray2Struct<T>(IntPtr unmanagedArray, int length, out T[] mangagedArray)
{
    var size = Marshal.SizeOf(typeof(T));
    mangagedArray = new T[length];

    for (int i = 0; i < length; i++)
    {
        IntPtr ins = new IntPtr(unmanagedArray.ToInt64() + i * size);
        mangagedArray[i] = Marshal.PtrToStructure<T>(ins);
    }
 }
2 голосов
/ 19 июля 2011

Структуры в C и C # - это не одно и то же.Одно из отличий состоит в том, что в C # вы должны явно требовать, чтобы ваша структура была последовательно размечена.Если вы не вписали атрибут [StructLayout(LayoutKind.Sequential)] или [StructLayout(LayoutKind.Explicit)] в свою структуру, я не верю, что вы можете управлять этим таким образом.Microsoft заявляет, что PtrToStructure должен использоваться для преобразования структур из неуправляемой в управляемую память

Вам следует проверить, помогает ли добавление этих атрибутов в вашу структуру, если это еще не помогает попытаться выделить память с помощью Marshal.AllocHGlobal(IntPtr)и используйте Marshal.Copy для инициализации вашей структуры, а затем попробуйте использовать PtrToStructure.Если это работает, то вы не можете использовать PtrToStructure с управляемой памятью

...