C# моется, C++ выделил память?

После моего теста версия 2.3.1 ZXing.NET.Mobile стабильна, вы можете использовать его.

9
задан Steve 26 March 2009 в 14:01
поделиться

4 ответа

Я полагаю, что необходимо использовать CoTaskMemAlloc () для памяти, которую Вы хотите явно освободить от управляемой стороны. CLR будет заботиться об освобождении памяти, после того как это больше не достижимо. Если Вы хотите освободить его явно, можно использовать управляемого Маршала. CoTaskFree () стандартная программа.

В целом interop marshaler и CLR соблюдают конвенции COM для освобождения памяти; получатель ответственен за освобождение памяти. Так CLR/Interop marshaler будет обычно заботиться об освобождении памяти, которая была выделена в собственном вызове, если та память возвращается управляемой вызывающей стороне.

Из памяти управление с Interop Marshaler (MSDN):

interop marshaler всегда пытается к свободной памяти, выделенной неуправляемым кодом. Это поведение выполняет правила управления памятью COM, но отличается от правил, которые управляют собственным C++.

Беспорядок может возникнуть при предупреждении собственного поведения C++ (никакое освобождение памяти), когда использование платформы вызывает, который автоматически освобождает память для указателей. Например, вызов следующего неуправляемого метода от DLL C++ автоматически не освобождает памяти.

Время выполнения всегда использует метод CoTaskMemFree для свободной памяти. Если бы память, с которой Вы работаете, не была выделена с методом CoTaskMemAlloc, то необходимо использовать IntPtr и освободить память вручную с помощью соответствующего метода.

8
ответ дан 4 December 2019 в 13:05
поделиться

Перенесите его в объект, который реализует IDisposable, и удостоверьтесь, что обертка C# расположена.

Вот блог, который я записал о простом способе реализовать IDisposable.

6
ответ дан 4 December 2019 в 13:05
поделиться

Книга.NET 2.0 Рецепта Interoperbility надеется быть удобной. Это, кажется, соглашается с тем, что Arnshea заявил о CoTaskMemFree.

1
ответ дан 4 December 2019 в 13:05
поделиться

Я почти на 100% уверен, что CLR автоматически не освободит память, выделенную для теста (если бы это был PInvoke, то я был бы на 100% уверен). Причем причина, как CLR знает то, что Вы раньше выделяли память во-первых? А именно, это не делает.

Более безопасный способ записать эту функцию следующие

void MemAlloc(ref IntPtr arrayPtr, int membercount)

После того как Вы получаете вызов назад, можно сделать следующее.

var count = GetTheCount();
var arrayPtr = IntPtr.Zero;
obj.MemAlloc(ref arrayPtr, count);
byte[] test = MarshalThePtrToByteArray(arrayPtr, count);
Marshal.FreeCoTaskMem(arrayPtr);

Вот быстрая и грязная реализация MarashalThePtrToByteArray

byte[] MarashalThePtrToByteArray(IntPtr ptr, int count) {
  byte[] arr = new byte[count];
  for ( int i = 0; i < count; i++ ) {
    arr[i] = (byte)Marshal.PtrToStructure(ptr, typeof(byte));
    ptr = new IntPtr(IntPtr.ToInt64() + Marshal.SizeOf(typeof(byte)));
  }
  return arr;
}
1
ответ дан 4 December 2019 в 13:05
поделиться
Другие вопросы по тегам:

Похожие вопросы: