2015-08-17 5 views
2

Je voudrais mieux comprendre le mappage des structures/classes quand il s'agit de traiter du code non managé.Faire un StructLayout sur une classe fonctionnant comme si elle fonctionnait sur une structure

J'ai défini la struct suivante:

[StructLayout(LayoutKind.Sequential)] 
    public struct ProfileInfo 
    { 
     public int dwSize; 
     public int dwFlags; 
     [MarshalAs(UnmanagedType.LPTStr)] public string lpUserName; 
     [MarshalAs(UnmanagedType.LPTStr)] public string lpProfilePath; 
     [MarshalAs(UnmanagedType.LPTStr)] public string lpDefaultPath; 
     [MarshalAs(UnmanagedType.LPTStr)] public string lpServerName; 
     [MarshalAs(UnmanagedType.LPTStr)] public string lpPolicyPath; 
     public IntPtr hProfile; 

     public ProfileInfo(string userName, string profilepath) 
     { 
     dwFlags = 1;  
     dwSize = Marshal.SizeOf<ProfileInfo>(); 
     lpUserName = userName; 
     lpServerName = null; 
     lpProfilePath = string.IsNullOrWhiteSpace(profilepath) ? null : profilepath; 
     lpPolicyPath = null; 
     lpDefaultPath = null; 
     hProfile = IntPtr.Zero; 
     } 
    } 

à utiliser avec la méthode folling:

 [DllImport("userenv.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "LoadUserProfileW")] 
     public static extern bool LoadUserProfile(IntPtr hToken, ref ProfileInfo lpProfileInfo); 

Bien qu'il fonctionne très bien aussi longtemps que ProfileInfo est un struct, LoadUserProfile commence à ne pas quand je faites ProfileInfo une classe.

Je me demandais pourquoi?
Pour moi, le StructLayout a été appliqué de la même manière sur une classe ou une structure. Quelles sont les différences possibles de représentation de la mémoire de ProfileInfo qui provoque l'échec de LoadUserProfile lorsque je le modifie de struct à class?

+1

Ma boule de cristal dit que vous avez oublié de retirer le mot-clé 'ref' de la déclaration d'argument. Obligatoire car les objets de classe sont toujours transmis par référence. Le meilleur moyen de poser une question à SO est de poster le code qui * ne fonctionne pas. –

Répondre

-1

En C++, les classes contiennent un pointeur caché 'this'. Je suppose que C# fait la même chose.

Dans l'image ci-dessous, pi est une structure, p2 est une classe. Vous pouvez voir à partir des vidages mémoire (pi sur la gauche, p2 sur la droite) que p2 a quelques octets supplémentaires qui est le pointeur caché.

enter image description here