2009-10-22 3 views
3

J'ai une DLL, qui est conçue en C++, incluse dans un projet C# et j'ai des AccessViolationExceptions étranges qui se produisent de manière non rationnelle. Je soupçonne que mes déchets ne sont pas collectés correctement. J'ai une méthode non gérée apiGetSettings (à partir de la DLL) qui devrait copier des données vers un objet Settings (en fait une structure dans le code original, mais .NET InterOp seulement autorisé l'importation des données en tant qu'objets de classe.J'utilise le System.Runtime.InteropServices. Les méthodes du maréchal pour allouer et désallouer la mémoire, mais il peut laisser des ordures derrière tout cela bloque tout.C# inter-marshaler et disposer

Maintenant, devrais-je implémenter des méthodes IDisposable dans la classe Settings (est-il non géré?) Si oui, comment je dispose des chaînes rassemblèrent comme UnmanagedType.ByValTStr et comment puis-je disposer des objets paramètres?

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); 
} 

Répondre

1

non, vous n'avez pas besoin de mettre en œuvre IDisposable. Votre classe Paramètres est une classe gérée (ces Attri les butes sont juste à des fins d'exécution) et seront ramassés. Ma première estimation: vous allouez 43 octets, mais vos deux chaînes totalisent plus de 70 octets (rappelez-vous, à moins que vous ne soyez sur Win98/Me, la taille d'un caractère est de 2 octets), donc vous ne pas allouer assez. Utilisez plutôt Marshal.SizeOf pour déterminer dynamiquement la taille de la structure.

+0

Merci, mon sauveur! Je n'aurais jamais pensé à ça autrement. Cela a résolu tous mes problèmes irrationnels des trois derniers mois. :) – entro

Questions connexes