WS_STRUCT_DESCRIPTION
構造体サイズ=各フィールドのバイト数(x64/x86 で異なる場合は x64/x86 と併記)。x64/x86 列=フィールドのバイトオフセット(HSPで dupptr / lpoke / wpoke 等に使用)。
フィールド
| フィールド | 型 | サイズ | x64 | x86 | 説明 |
|---|---|---|---|---|---|
| size | DWORD | 4 | +0 | +0 | 構造体のサイズ (バイト単位)。 |
| alignment | DWORD | 4 | +4 | +4 | 構造体のアラインメント要件。1 から 8 までの 2 のべき乗でなければなりません。 |
| fields | WS_FIELD_DESCRIPTION** | 8/4 | +8 | +8 | 構造体の各フィールドの記述へのポインターの配列。 この配列内でのフィールドの順序については、「解説」セクションを参照してください。 |
| fieldCount | DWORD | 4 | +16 | +12 | fields 配列内のフィールドの数。フィールドで表現されない構造体の部分は、初期化されないまま残されます。2 つのフィールド記述が構造体の同じオフセットを参照することはできません。 |
| typeLocalName | WS_XML_STRING* | 8/4 | +24 | +16 | 構造体の XML 型名。これは構造体が他の構造体から派生する場合にのみ使用され、それ以外の場合は NULL でもかまいません。 |
| typeNs | WS_XML_STRING* | 8/4 | +32 | +20 | 構造体の XML 型名前空間。これは構造体が他の構造体から派生する場合にのみ使用され、それ以外の場合は NULL でもかまいません。 |
| parentType | WS_STRUCT_DESCRIPTION* | 8/4 | +40 | +24 | この型の派生元となる型。これは構造体が他の構造体から派生する場合にのみ使用され、それ以外の場合は NULL でもかまいません。 |
| subTypes | WS_STRUCT_DESCRIPTION** | 8/4 | +48 | +28 | 派生型へのポインターの配列。これは構造体が他の構造体から派生する場合にのみ使用され、それ以外の場合は NULL でもかまいません。 |
| subTypeCount | DWORD | 4 | +56 | +32 | subTypes 配列内の型の数。これは構造体が他の構造体から派生する場合にのみ使用され、それ以外の場合は NULL でもかまいません。 |
| structOptions | DWORD | 4 | +60 | +36 | 構造体のシリアライズ動作を制御するフラグの組み合わせ。 |
公式ドキュメント
C 構造体型に関する情報と、それが XML 要素にどのようにマップされるかを示します。これは WS_STRUCT_TYPE と共に使用します。
解説(Remarks)
構造体内のフィールドの順序を記述する文法は次のとおりです。順序は、各 WS_FIELD_DESCRIPTION の mapping フィールドに基づいて定義されます。
Fields := TypeAttributeField? AttributeField* ContentFields UnmappedFields*
ContentFields := TextContentField | ElementContentFields
ElementContentFields := ElementContentField* ? AnyElementField?
ElementContentField := ElementField | RepeatingElementField | ElementChoiceField | RepeatingElementChoiceField
ElementField := WS_ELEMENT_FIELD_MAPPING
RepeatingElementField := WS_REPEATING_ELEMENT_FIELD_MAPPING
ElementChoiceField := WS_ELEMENT_CHOICE_FIELD_MAPPING
RepeatingElementChoiceField := WS_REPEATING_ELEMENT_CHOICE_FIELD_MAPPING
AnyElementField := WS_ANY_ELEMENT_FIELD_MAPPING
TextContentField := WS_TEXT_FIELD_MAPPING
UnmappedField := WS_NO_FIELD_MAPPING
TypeAttributeField := WS_TYPE_ATTRIBUTE_FIELD_MAPPING
AttributeField := WS_ATTRIBUTE_FIELD_MAPPING
構造体のフィールド記述は、指定された順序でシリアル化および逆シリアル化されることに注意してください。逆シリアル化の処理は「貪欲 (greedy)」です。つまり、次のフィールド記述が考慮される前に、特定のフィールド記述の定義に一致する内容が可能な限り多く消費されます。この方式により、内容が現在のフィールド記述と後続のフィールド記述のどちらにも一致し得る場合のあいまいさが解決されます。
逆シリアル化の処理は制限的でもあります。すべての内容はフィールド記述に従って逆シリアル化されなければなりません。既定では、処理されない要素や属性があると逆シリアル化の処理は失敗します。ただし、WS_STRUCT_IGNORE_TRAILING_ELEMENT_CONTENT フラグが設定されている場合、要素の末尾の内容は無視されて破棄されます。同様に、WS_STRUCT_IGNORE_UNHANDLED_ATTRIBUTES フラグが設定されている場合、処理されない属性は無視されて破棄されます。
WS_FIELD_DESCRIPTION 構造体はオフセットを使用して構造体内の実際のフィールドの位置を決定するため、構造体内でのフィールドの実際の順序に制限はないことに注意してください。
ある構造体が別の構造体から派生する (拡張する) 場合、両方の構造体のフィールドを派生構造体の記述に含める必要があり、上記の文法を維持しなければなりません。例:
struct BaseStructure
{
const WS_STRUCT_DESCRIPTION* _type;
int baseAttribute;
int baseElement;
};
// BaseStructure field descriptions:
// WS_TYPE_ATTRIBUTE_FIELD_MAPPING // _type
// WS_ATTRIBUTE_FIELD_MAPPING // baseAttribute
// WS_ELEMENT_FIELD_MAPPING // baseElement
struct DerivedStructure
{
struct BaseStructure _base;
int derivedAttribute;
int derivedElement;
};
// DerivedStructure field descriptions:
// WS_TYPE_ATTRIBUTE_FIELD_MAPPING // _type
// WS_ATTRIBUTE_FIELD_MAPPING // baseAttribute
// WS_ATTRIBUTE_FIELD_MAPPING // derivedAttribute
// WS_ELEMENT_FIELD_MAPPING // baseElement
// WS_ELEMENT_FIELD_MAPPING // derivedElement
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)
各言語での定義
#include <windows.h>
// WS_STRUCT_DESCRIPTION (x64 64 / x86 40 バイト)
typedef struct WS_STRUCT_DESCRIPTION {
DWORD size;
DWORD alignment;
WS_FIELD_DESCRIPTION** fields;
DWORD fieldCount;
WS_XML_STRING* typeLocalName;
WS_XML_STRING* typeNs;
WS_STRUCT_DESCRIPTION* parentType;
WS_STRUCT_DESCRIPTION** subTypes;
DWORD subTypeCount;
DWORD structOptions;
} WS_STRUCT_DESCRIPTION;using System;
using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct WS_STRUCT_DESCRIPTION
{
public uint size;
public uint alignment;
public IntPtr fields;
public uint fieldCount;
public IntPtr typeLocalName;
public IntPtr typeNs;
public IntPtr parentType;
public IntPtr subTypes;
public uint subTypeCount;
public uint structOptions;
}Imports System.Runtime.InteropServices
<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)>
Public Structure WS_STRUCT_DESCRIPTION
Public size As UInteger
Public alignment As UInteger
Public fields As IntPtr
Public fieldCount As UInteger
Public typeLocalName As IntPtr
Public typeNs As IntPtr
Public parentType As IntPtr
Public subTypes As IntPtr
Public subTypeCount As UInteger
Public structOptions As UInteger
End Structureimport ctypes
from ctypes import wintypes
class WS_STRUCT_DESCRIPTION(ctypes.Structure):
_fields_ = [
("size", wintypes.DWORD),
("alignment", wintypes.DWORD),
("fields", ctypes.c_void_p),
("fieldCount", wintypes.DWORD),
("typeLocalName", ctypes.c_void_p),
("typeNs", ctypes.c_void_p),
("parentType", ctypes.c_void_p),
("subTypes", ctypes.c_void_p),
("subTypeCount", wintypes.DWORD),
("structOptions", wintypes.DWORD),
]#[repr(C)]
pub struct WS_STRUCT_DESCRIPTION {
pub size: u32,
pub alignment: u32,
pub fields: *mut core::ffi::c_void,
pub fieldCount: u32,
pub typeLocalName: *mut core::ffi::c_void,
pub typeNs: *mut core::ffi::c_void,
pub parentType: *mut core::ffi::c_void,
pub subTypes: *mut core::ffi::c_void,
pub subTypeCount: u32,
pub structOptions: u32,
}import "golang.org/x/sys/windows"
type WS_STRUCT_DESCRIPTION struct {
size uint32
alignment uint32
fields uintptr
fieldCount uint32
typeLocalName uintptr
typeNs uintptr
parentType uintptr
subTypes uintptr
subTypeCount uint32
structOptions uint32
}type
WS_STRUCT_DESCRIPTION = record
size: DWORD;
alignment: DWORD;
fields: Pointer;
fieldCount: DWORD;
typeLocalName: Pointer;
typeNs: Pointer;
parentType: Pointer;
subTypes: Pointer;
subTypeCount: DWORD;
structOptions: DWORD;
end;const WS_STRUCT_DESCRIPTION = extern struct {
size: u32,
alignment: u32,
fields: ?*anyopaque,
fieldCount: u32,
typeLocalName: ?*anyopaque,
typeNs: ?*anyopaque,
parentType: ?*anyopaque,
subTypes: ?*anyopaque,
subTypeCount: u32,
structOptions: u32,
};type
WS_STRUCT_DESCRIPTION {.bycopy.} = object
size: uint32
alignment: uint32
fields: pointer
fieldCount: uint32
typeLocalName: pointer
typeNs: pointer
parentType: pointer
subTypes: pointer
subTypeCount: uint32
structOptions: uint32struct WS_STRUCT_DESCRIPTION
{
uint size;
uint alignment;
void* fields;
uint fieldCount;
void* typeLocalName;
void* typeNs;
void* parentType;
void* subTypes;
uint subTypeCount;
uint structOptions;
}HSP用 定義
HSP3.7/3.8 は構造体機能が無いため4byte整数配列(dim)+peek/poke で操作(32/64bitでサイズ・位置が異なる場合はタブで分割)。IronHSP は NSTRUCT(#defstruct/stdim/->)で32/64bit共通。
; HSP3.7/3.8 は構造体機能が無いため、4byte整数の配列変数で操作します。(x86 レイアウト)
; WS_STRUCT_DESCRIPTION サイズ: 40 バイト(x86)
dim st, 10 ; 4byte整数×10(構造体サイズ 40 / 4 切り上げ)
; size : DWORD (+0, 4byte) st.0 = 値 / 値 = st.0 (lpoke/lpeek も可)
; alignment : DWORD (+4, 4byte) st.1 = 値 / 値 = st.1 (lpoke/lpeek も可)
; fields : WS_FIELD_DESCRIPTION** (+8, 4byte) varptr(st)+8 を基点に操作(4byte:入れ子/配列)
; fieldCount : DWORD (+12, 4byte) st.3 = 値 / 値 = st.3 (lpoke/lpeek も可)
; typeLocalName : WS_XML_STRING* (+16, 4byte) varptr(st)+16 を基点に操作(4byte:入れ子/配列)
; typeNs : WS_XML_STRING* (+20, 4byte) varptr(st)+20 を基点に操作(4byte:入れ子/配列)
; parentType : WS_STRUCT_DESCRIPTION* (+24, 4byte) varptr(st)+24 を基点に操作(4byte:入れ子/配列)
; subTypes : WS_STRUCT_DESCRIPTION** (+28, 4byte) varptr(st)+28 を基点に操作(4byte:入れ子/配列)
; subTypeCount : DWORD (+32, 4byte) st.8 = 値 / 値 = st.8 (lpoke/lpeek も可)
; structOptions : DWORD (+36, 4byte) st.9 = 値 / 値 = st.9 (lpoke/lpeek も可)
; ※4byte境界の整数は添字 st.N(N=オフセット/4)で読み書き可。それ以外は peek/poke 系を使用。; HSP3.7/3.8 は構造体機能が無いため、4byte整数の配列変数で操作します。(x64 レイアウト)
; WS_STRUCT_DESCRIPTION サイズ: 64 バイト(x64)
dim st, 16 ; 4byte整数×16(構造体サイズ 64 / 4 切り上げ)
; size : DWORD (+0, 4byte) st.0 = 値 / 値 = st.0 (lpoke/lpeek も可)
; alignment : DWORD (+4, 4byte) st.1 = 値 / 値 = st.1 (lpoke/lpeek も可)
; fields : WS_FIELD_DESCRIPTION** (+8, 8byte) varptr(st)+8 を基点に操作(8byte:入れ子/配列)
; fieldCount : DWORD (+16, 4byte) st.4 = 値 / 値 = st.4 (lpoke/lpeek も可)
; typeLocalName : WS_XML_STRING* (+24, 8byte) varptr(st)+24 を基点に操作(8byte:入れ子/配列)
; typeNs : WS_XML_STRING* (+32, 8byte) varptr(st)+32 を基点に操作(8byte:入れ子/配列)
; parentType : WS_STRUCT_DESCRIPTION* (+40, 8byte) varptr(st)+40 を基点に操作(8byte:入れ子/配列)
; subTypes : WS_STRUCT_DESCRIPTION** (+48, 8byte) varptr(st)+48 を基点に操作(8byte:入れ子/配列)
; subTypeCount : DWORD (+56, 4byte) st.14 = 値 / 値 = st.14 (lpoke/lpeek も可)
; structOptions : DWORD (+60, 4byte) st.15 = 値 / 値 = st.15 (lpoke/lpeek も可)
; ※4byte境界の整数は添字 st.N(N=オフセット/4)で読み書き可。それ以外は peek/poke 系を使用。; IronHSP は NSTRUCT(構造体)をサポート。32bit/64bit どちらでも同じコードで動作します。
#defstruct global WS_STRUCT_DESCRIPTION
#field int size
#field int alignment
#field intptr fields
#field int fieldCount
#field intptr typeLocalName
#field intptr typeNs
#field intptr parentType
#field intptr subTypes
#field int subTypeCount
#field int structOptions
#endstruct
stdim st, WS_STRUCT_DESCRIPTION ; NSTRUCT 変数を確保
st->size = 100
mes "size=" + st->size