P-Invoke Разобрать массив структур, размещенных в DLL - PullRequest
2 голосов
/ 15 февраля 2011

У меня есть требование переложить большие объемы (теоретически до нескольких терабайт, ограниченных только доступной памятью) данных из базовой библиотеки DLL на C / C ++, которая управляет, фильтрует и выделяет данные, в графический интерфейс C # (который только читает данные). Было бы оптимальным, если бы данные никогда не дублировались, а были доступны только по ссылке из C #. Подпись моего метода DLL в настоящее время следующая (я могу внести изменения там):

extern "C" {

typedef struct {
    wchar_t* name;
    __int32 t;
    float v;
    bool condition;

    } TestData;

__declspec(dllexport) void fillTestArrayWithAlloc(TestData** td, __int32* size);
};

Длина массива неизвестна C # и может составлять от 1 до миллионов ....

Я отобразил структуру следующим образом:

   [StructLayout(LayoutKind.Sequential)]
   struct TestData
    {
        [MarshalAs(UnmanagedType.LPWStr)]
        public String name;
        public Int32 t;
        [MarshalAs(UnmanagedType.R4)]
        public float v; 
        public bool condition;

    }

Я пробовал оба способа ручного распаковки, как это

static extern void fillTestArrayWithAlloc(ref IntPtr td, ref int size);

и автоматическое распаковка, как это

static extern void fillTestArrayWithAlloc([Out] TestData[] td, ref int size);

Но в обоих случаях он выполняет копирование памяти, что нежелательно. Есть ли способ сделать это без копирования данных?

С наилучшими пожеланиями Petr

1 Ответ

1 голос
/ 15 февраля 2011

Первая версия объявления вашей функции не должна вызывать копирование всех данных: маршалируются только указатель и значение длины.

Я думаю, что тогда вы сможете реализовать итератор или перечислитель, который одновременно марширует одну TestData структуру непосредственно из неуправляемой памяти, на которую указывает IntPtr, используя Marshal.PtrToStructure. Вам нужно будет сделать некоторую арифметику указателя unsafe для перехода от одного экземпляра к другому во время итерации.

При таком подходе следует избегать оптового копирования всей структуры. Удачи.

...