6

MSDN ブログの記事を読んだ後に疑問が生じます。. この記事では、 aFILETIMEを anにキャストすると、位置合わせされていない__int64ポインターが作成される可能性があると述べています。

FILETIMELUID、およびLUID_AND_ATTRIBUTESstructs は、次のように Windows ヘッダーで宣言されています。

  typedef struct FILETIME {
      DWORD dwLowDateTime;
      DWORD dwHighDateTime;
  }

  typedef struct LUID {
      ULONG LowPart;
      LONG  HighPart;
  }

  typedef struct LUID_AND_ATTRIBUTES {
      LUID  Luid;
      DWORD Attributes;
  }

FILETIMELUIDstructs は同様のレイアウトを持っているため、 a も として扱うと、LUID位置合わせされていない__int64ポインターが作成される可能性があります。ただし、Windows.pas(ここでは Delphi XE3) これを実践しています。たとえば、次のようになります。

  {$ALIGN 4}
  LUID_AND_ATTRIBUTES = record
    Luid      : Int64;  // Here, LUID is treated as Int64
    Attributes: DWORD;
  end;
  {$ALIGN ON}

別の例は

  function LookupPrivilegeValue(lpSystemName, lpName: LPCWSTR;
      var lpLuid: Int64): BOOL; stdcall; // LUID is treated as Int64

/の  ようにFILETIME、またはLUID 直接構造体を安全に扱う方法は? キーは何ですか?UInt64Int64

4

1 に答える 1

5

これは、Delphiがサポートするアーキテクチャではほとんど問題になりません。x86およびx64アーキテクチャでは、位置がずれているデータにアクセスした場合でも問題はありません。一方、Itaniumでミスアライメントされたデータにアクセスすると、ランタイムエラーが発生します。しかし、DelphiはItaniumをターゲットにしませんでした。

重要な問題は、レコードのレイアウトです。Int64のアラインメントは8ですが、FILETIMEとLUIDのアラインメントは4です。そのため、LUID_AND_ATTRIBUTESは明示的な$ALIGN4でマークされています。

FILETIMEとLUIDをInt64として宣言する場合は、レコードにレコードレイアウトを含めるたびに、レコードレイアウトに特別な注意を払う必要があります。

于 2012-11-21T07:07:57.997 に答える