Вопрос

У меня есть DLL, разработанная на C ++, включенная в проект на C #, и у меня есть странные исключения AccessViolationException, происходящие нерационально. Я подозреваю, что мой мусор неправильно собран. У меня есть неуправляемый метод apiGetSettings (из DLL), который должен копировать данные в объект настроек (на самом деле это структура в исходном коде, но .NET InterOp позволяет импортировать данные только как объекты класса. Я использую System.Runtime.InteropServices. Маршал использует методы для выделения и освобождения памяти, но это может оставить мусор, который разрушает все.

Теперь я должен реализовать методы IDisposable в классе Settings (это неуправляемо?). Если да, как я могу избавиться от строк, маршализованных как UnmanagedType.ByValTStr, и как я могу избавиться от объектов настроек?

using System.Runtime.InteropServices;

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
class Settings
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 33)]
internal string d;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 6)]
internal string t;
internal int b;
}

[DllImport(".\\foobar.dll", EntryPoint = "getSettings")]
private static extern int apiGetSettings(IntPtr pointerToSettings);

void GetSettings(ref Settings settings)
{
int debug = 0;

// Initialize a pointer for the structure and allocate memory
IntPtr pointerToSettings = Marshal.AllocHGlobal(43);

// Connect the pointer to the structure
Marshal.StructureToPtr(settings, pointerToSettings, true);

// Point the pointer
debug = apiGetSettings(pointerToSettings);

// Copy the pointed data to the structure
Marshal.PtrToStructure(pointerToSettings, settings);

// Free the allocated memory
Marshal.FreeHGlobal(pointerToSettings);
}
Это было полезно?

Решение

Нет, вам не нужно реализовывать IDisposable. Ваш класс настроек является управляемым классом (эти атрибуты предназначены только для целей выполнения) и будет собирать мусор.

Мое первое предположение: вы выделяете 43 байта, но обе ваши строки добавляют до 70 байтов (помните, если вы не используете древнюю Win98 / Me, размер одного символа составляет 2 байта), так что вы ' не выделяет достаточно. Вместо этого используйте Marshal.SizeOf для динамического определения размера структуры.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top