Как освободить память, выделенную в C # для IntPtr, передаваемой из C ++ dll? - PullRequest
0 голосов
/ 27 февраля 2019

Указатель передается мне из библиотеки C ++ следующим образом:

[DllImport("myfile.dll", EntryPoint = "LoadFile", SetLastError = true, CharSet = CharSet.None)]
public static extern IntPtr dLoadFile(string x);

IntPtr p = dLoadFile("myfile");

//Do things with p.

Marshal.FreeHGlobal(p) //crash on this line with exception below.

System.Runtime.InteropServices.COMException: 'Один или несколько аргументов недопустимы (Исключение из HRESULT: 0x80000003)'

Должен ли я освободить память, выделенную для IntPtr?И если да, то как это сделать правильно?Очевидно, кажется, что Marshal.FreeHGlobal () - это не тот путь, по которому ...

Спасибо

1 Ответ

0 голосов
/ 27 февраля 2019

Общее правило заключается в том, что «кто выделяет ресурсы, должен быть вызван для выполнения очистки».В c # вы не владеете памятью: ей владеет clr.Ваши общие сборки c # также совместно используют clr, поэтому у вас создается впечатление, что вы создаете объект в одной сборке и освобождаете его в другой.При выполнении взаимодействия ресурс, созданный библиотекой, должен быть очищен той же библиотекой через дополнительный экспортированный API-интерфейс.Однако есть некоторые исключения, которые относятся к моменту создания объектов операционной системы: в соответствии со специальной документацией рассматриваемого объекта вы можете освободить ресурс на сайте вызывающей стороны.

В вашем случае вам следует экспортироватьсоответствующие api в моем файле file.dll, которые правильно выполняют очистку.

Это правило позволяет вам не раскрывать внутренние детали, что позволяет вам изменять ваши внутренние данные, не нарушая вызывающего.

...