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])
{defaults ...} 句により、クラスにいくつかの既定値を設定できるようになります。これは
define-dll-class の
defaults 句と同じ値をサポートしますが、
string-rep 属性だけは
define-C-struct の意味を持ちます。
通常のクラスとは異なり、define-C-struct クラスは他のクラスから継承できません。その他のクラスが define-C-struct クラスから継承することもできません。オプションを除き、define-C-struct には標準のクラス メンバの型を含むことができます。
define-C-struct の定義で明示的にコンストラクタが定義されていない場合、引数を取らず、すべてのフィールドを null または 0 に初期化する既定のコンストラクタが自動的に生成されます。
オブジェクトのインスタンス自体、およびフィールドのいずれかに割り当てられた任意のオブジェクトは
pin-object を使用して自動的にメモリに固定されるため、ユーザーがこれを行う必要はありません。
CHOOSECOLOR struct は次のように定義されます。
typedef struct {
DWORD lStructSize;
HWND hwndOwner;
HWND hInstance;
COLORREF rgbResult;
COLORREF *lpCustColors;
DWORD Flags;
LPARAM lCustData;
LPCCHOOKPROC lpfnHook;
LPCCTSTR lpTemplateName;
} CHOOSECOLOR, *LPCHOOSECOLOR;
DWORD、COLORREF、および 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);
}