define-C-struct (マクロ)
パッケージ: CURL.LANGUAGE.DLL-INTERFACE

構文

{define-C-struct [access] [modifiers] Name
    [{defaults key = value, ...}]
    ...
    field-definitions
    ...
}

外部データ構造へのインターフェイスを定義します。

access: クラスにアクセスできるコードを指定します。通常のクラスと同じです。publiclibrary および package (既定)。詳細については、「クラスへのアクセス」を参照してください。
modifiers: 追加修飾子の空白区切りリストです。define-C-struct でサポートされる唯一の値は deprecated です。
Name: クラスの名前。

説明

C 言語の struct などの外部データ構造へのインターフェイスとして機能する特別クラスを定義します。
define-C-struct オブジェクトは意味的に struct へのポインタのように動作します。unsafe-memory-get を使用して CPointer から define-C-struct インスタンスに変換できます (ポインタが実際に struct のインスタンスを参照する場合)。
定義には外部データ構造のレイアウトを指定する 1 つ以上のフィールド定義が含まれる必要があります。これらのフィールドは、標準の field 定義に似ていますが、フィールドの型は valid-dll-out-type? に受け入れられる型に制限され、初期値は許可されておらず、唯一のサポートされるフィールド修飾子は deprecated です。dll-method 宣言への引数と同様、フィールドが Curl 文字列型の 1 つを使用する場合、次の構文を使用して StringBuf の表現型と最大長を指定できます。
(rep = CString-type [, max-size = size])
型の直後です。詳細については、dll-method を参照してください。
{defaults ...} 句により、クラスにいくつかの既定値を設定できるようになります。これは define-dll-classdefaults 句と同じ値をサポートしますが、string-rep 属性だけは define-C-struct の意味を持ちます。
通常のクラスとは異なり、define-C-struct クラスは他のクラスから継承できません。その他のクラスが define-C-struct クラスから継承することもできません。オプションを除き、define-C-struct には標準のクラス メンバの型を含むことができます。
define-C-struct の定義で明示的にコンストラクタが定義されていない場合、引数を取らず、すべてのフィールドを null または 0 に初期化する既定のコンストラクタが自動的に生成されます。
オブジェクトのインスタンス自体、およびフィールドのいずれかに割り当てられた任意のオブジェクトは pin-object を使用して自動的にメモリに固定されるため、ユーザーがこれを行う必要はありません。

次の例では、Windows ChooseColor() 関数によって使用される Windows CHOOSECOLOR 構造体 が、define-C-struct を使用してどのように表示されるかを示しています。この例の、実行可能でより高度なバージョンは、curl://install/docs/default/examples/dguide/dll-interface.zip 内のファイル choose-color.curl にあります。この .zip ファイルの使用に関する詳細については、「アプレットの拡張」を参照してください。
CHOOSECOLOR struct は次のように定義されます。
typedef struct {
    DWORD        lStructSize;
    HWND         hwndOwner;
    HWND         hInstance;
    COLORREF     rgbResult;
    COLORREF    *lpCustColors;
    DWORD        Flags;
    LPARAM       lCustData;
    LPCCHOOKPROC lpfnHook;
    LPCCTSTR     lpTemplateName;
} CHOOSECOLOR, *LPCHOOSECOLOR;
DWORDCOLORREF、および LPARAM は 32 ビット整数で、HWND はポインタとして扱うことができるハンドルです。LPCCHOOKPROC は関数ポインタで、LPCCTSTR は null で終了する文字列へのポインタです。結果は rgbResult フィールドで返されます。このフィールドは赤が低順位 8 ビット、緑が次の 8 ビット、青がその後の 8 ビットでエンコードされます。CC_RGBINIT フラグが設定される場合は、既定の色もこのフィールドに配置できます。
これは次の define-C-struct で表します。
{let public constant WindowsHook:ProcType =
    {proc-type {hwnd:CPointer, msg:int, l:int, w:int}:CPointer}
}

{define-C-struct public ChooseColorStruct
  
  || Flag values
  let public constant CC_RGBINIT:int = 0x0001
 
  field public size:int
  field public owner:CPointer
  field public instance:CPointer
  field private _rgb:int
  field public custom-colors:{CArray-of int}
  field public flags:int
  field public data:CPointer
  field public hook:{StdcallCallback-to #WindowsHook}
  field public template-name:#String (rep = CString)
  
  {getter public {color}:Color
      let rgb:int = self._rgb
      {return
          {Color.from-rgb-uint8
              {bit-and 0xff, rgb},
              {bit-and 0xff, {bit-srl rgb, 8}},
              {bit-and 0xff, {bit-srl rgb, 16}}
          }
      }
  }
  {setter public {color color:Color}:void
      let pixel:Pixel = {color.to-Pixel}
      set self._rgb =
          {bit-or
              pixel.red-as-uint8,
              {bit-sll pixel.green-as-uint8, 8},
              {bit-sll pixel.blue-as-uint8, 16}
          }
  }

 {constructor public {default color:#Color = null}
   set self.size = 36
   set self.flags = ChooseColorInfo.CC_RGBINIT
   set self.custom-colors = {{CArray-of int} 16}
   set self.color =
       {if-non-null color then
           color
        else
           {Color.from-string "white"}
       }
 }
}
Curl 言語は Color クラスを持ちますが、_rgb フィールドを非表示にし、color ゲッターおよびセッターから便利なアクセスを提供します。template-name フィールド (rep = CString) の表示型は、このクラスに defaults 句が含まれている場合は省略できます。
{defaults string-rep = CString}
CC_RGBINIT フラグの値は、適切な Windows ヘッダー ファイルを検索して決定されます。特定のフラグを含む正確なヘッダーを検索するのは難しい場合があるため、たとえば次のように、値を出力する単純な C プログラムを記述するほうが簡単な場合があります。
#include <stdio.h>
#include <windows.h>

void main()
{
    printf("CC_RGBINIT == 0x%X\n", CC_RGBINIT);
}