2009-10-22 3 views
3

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

Теперь, нужно ли реализовывать методы 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); 
} 

ответ

1

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

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

+0

Спасибо, мой спаситель! Я бы никогда об этом не подумал. Это позволило решить все мои иррациональные проблемы за последние три месяца. :) – entro