Выделить память в C ++ DLL, бесплатно в C # - PullRequest
0 голосов
/ 17 мая 2019

Я новичок в C # и пытаюсь общаться C # с C ++ dll. Моя основная цель - выделить память в C # с помощью Marshal.AllocHGlobal(), присвоить ей значения и передать ссылку на IntPtr в C ++ dll. На стороне C ++ dll я меняю выделенный объем памяти с помощью malloc(), назначаю переменные. В конце я печатаю значения в C #. До этого момента все отлично работает.

Но когда я пытаюсь освободить выделенную память в C # с помощью Marshal.FreeHGlobal(), я получаю ошибку.

На самом деле, я много ищу, как мне реализовать свой код с этими функциями. Я нашел решение, которое говорит, что я должен написать функцию в DLL для освобождения памяти и вызвать эту функцию. Но мой менеджер сказал мне, мне нужно сделать эту работу на стороне C #. Поэтому я не могу использовать это решение. Кроме того, я нашел некоторые другие идеи, которые используют COM, но менеджер не хочет использовать COM. Поэтому я не могу использовать COM. Вот некоторые коды;

Распределение памяти в C #

var offset = 0;
var size = Marshal.SizeOf(typeof(dVehicle)) * denemeVehicle.Count();
IntPtr vehPnt;
vehPnt = Marshal.AllocHGlobal(size);

for(var i = 0; i < denemeVehicle.Count(); i++)
{
    Marshal.StructureToPtr(denemeVehicle[i], new IntPtr(vehPnt.ToInt64() + offset), false);
    offset += Marshal.SizeOf(typeof(dVehicle));
}

Изменение размера выделенной памяти в C ++

*vehicles = (dVehicle*) malloc(sizeof(dVehicle) * (new_VehSize));

Освободить выделенную память

Marshal.FreeHGlobal(vehPnt); // The error shows up in here

А это сообщение об ошибке;

Указатель недействителен. (Исключение из HRESULT: 0x80070006 (E_HANDLE))

1 Ответ

3 голосов
/ 17 мая 2019

Marshal.FreeHGlobal() не может освободить память, которая была выделена с помощью функции C malloc().Память должна быть «из глобальной кучи, выделенной [Marshal.] AllocHGlobal, [Marshal.] ReAllocHGlobal, или любым эквивалентным неуправляемым методом API ».

Внутренне Marshal.AllocHGlobal() и Marshal.FreeHGlobal() используют функции Win32 LocalAlloc() и LocalFree().Это задокументировано в MSDN.

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

Если два модуля совместно используют память друг с другом, но не согласны с общим диспетчером памяти (например, предоставленным ОС), то модуль, который выделяет память, должен быть тем же модулем, чтобы освободить ее, поскольку это единственный модуль, который знает, как была выделена память и, следовательно, как ее освободить.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...