1

Free Pascalでゲーム用のSDL /input ライブラリを作成していますが、問題に直面しています。

ある要素にアクセスすると、他の要素が変更されるバリアント レコードがあります。

レコード タイプは次のとおりです。

tInput = Record
    case Device: TInputDevice of
        ID_KeyOnce, ID_KeyCont:                     (Key:         TSDLKey);
        ID_MouseButton:                             (MouseButton: Byte);
        ID_MouseAxis, ID_JoyAxis,
          ID_JoyBall, ID_JoyHat:                    (Axis:        Byte);
        ID_JoyButton, ID_JoyButtonOnce, ID_JoyAxis,
          ID_JoyHat, ID_JoyBall:                    (Which:       Byte);
        ID_JoyButton, ID_JoyButtonOnce:             (Button:      Byte);

終わり;

クラッシュするコードは次のとおりです。

with Input do begin
    Device := ID_JoyAxis;
    Which  := 0;
    Axis   := 1;
end;

軸が 1 に設定されている場合、レコード内の他の変数はすべて 1 2 になります。

これは既知のバグですか? または、私が認識していない機能ですか?それとも私が台無しにしたものですか?

4

1 に答える 1

1

これは共用体と呼ばれ、このタイプのレコード宣言の意図された動作です。

case Device : TInputDevice of

……ここが「魔法」です。

ユニオンでは、メンバーのストレージは「共有」されます。

編集:バイトオフセットに関してあなたが持っているレコードを取ります(...という仮定の下でsizeof(TSDLKey) = 4):

------------------------------------------------
00 | Key | MouseButton | Axis | Which | Button |
---|     |-------------|------|-------|--------|
01 |     |             |      |       |        |
---|     |-------------|------|-------|--------|
02 |     |             |      |       |        |
---|     |-------------|------|-------|--------|
03 |     |             |      |       |        |
------------------------------------------------

私が知っているルールでは、TInputDevice は列挙型である必要があります。そうでない場合は、明示的に指定する必要Integerがあります。

type xyz = record
  case integer of
  0: (foo: Byte);
  1: (bar: Integer);
end;

注意:バリアント型では、どのユニオン メンバーを選択して有効にするかを 1 つのメンバーに記述するのが通例です (ネストされたユニオン)。

于 2011-03-02T03:39:34.080 に答える