Pergunta

Eu tenho uma DLL, que é projetado em C ++, incluído em um projeto C # e eu tenho AccessViolationExceptions estranhas acontecendo unrationally. Eu suspeito que o meu lixo não é coletado corretamente. Eu tenho um não gerenciados apiGetSettings método (a partir da DLL), que deve copiar os dados para um objeto Configurações (na verdade um struct no código original, mas interoperabilidade .NET só é permitido importar os dados como objetos de classe. Eu uso os System.Runtime.InteropServices. métodos Marshal para alocar e desalocar memória, mas pode deixar lixo para trás que trava tudo.

Agora, eu deveria implementar métodos IDisposable na classe Configurações (é não gerenciado?). Se sim, como faço para eliminar as cordas mobilizados no UnmanagedType.ByValTStr e como faço para eliminar as configurações de objetos?

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);
}
Foi útil?

Solução

Não, você não precisa implementar IDisposable. Sua classe Configurações é uma classe gerenciada (esses atributos são apenas para fins de tempo de execução) e será lixo coletado.

Meu primeiro palpite: você está alocando 43 bytes, mas ambas as suas cordas somam mais de 70 bytes (lembre-se, a menos que você está na antiga Win98 / Me, do tamanho de um caractere é de 2 bytes), para que' re não alocar suficiente. Use Marshal.SizeOf em vez de dinamicamente detemine o tamanho da estrutura.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top