2

アンマネージ コードを扱う場合、構造体/クラスのマッピングをよりよく理解したいと思います。

次の構造体を定義しました。

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

次の方法で使用します。

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

構造体である限りうまく機能しますが、クラス ProfileInfoを作成すると LoadUserProfile が失敗し始めます。ProfileInfo

なぜだろう?
私にとって、 StructLayout はクラスまたは構造体に同じ方法で適用されました。

LoadUserProfile を struct から class に変更すると失敗する ProfileInfo のメモリ表現の違いは何ですか?

4

1 に答える 1

-1

C++ では、クラスに非表示の「this」ポインターが含まれています。C#も同じことをしていると思います。

下の画像で、pi は構造体、p2 はクラスです。メモリ ダンプ (左が pi、右が p2) から、p2 には隠しポインタである余分なバイトがあることがわかります。

ここに画像の説明を入力

于 2015-08-17T15:47:58.033 に答える