Win32 API 日本語リファレンス
ホームNetworking.WindowsWebServices › WS_UNION_DESCRIPTION

WS_UNION_DESCRIPTION

構造体
サイズx64: 40 バイト / x86: 28 バイト

サイズ=各フィールドのバイト数(x64/x86 で異なる場合は x64/x86 と併記)。x64/x86 列=フィールドのバイトオフセット(HSPで dupptr / lpoke / wpoke 等に使用)。

フィールド

フィールドサイズx64x86説明
sizeDWORD4+0+0構造体のサイズ (バイト単位) です。
alignmentDWORD4+4+4構造体のアラインメント要件です。これは 1 から 8 までの 2 のべき乗でなければなりません。
fieldsWS_UNION_FIELD_DESCRIPTION**8/4+8+8

共用体のフィールドの記述へのポインターの配列です。

この配列内のフィールドの順序については、解説セクションを参照してください。

fieldCountDWORD4+16+12fields 配列内のフィールドの数です。フィールドで表現されない構造体の部分は 未初期化のままになります。フィールドの記述は、構造体の同じオフセットを 参照してもかまいません (たとえば、それらがすべて単一の共用体の一部である場合)。
enumOffsetDWORD4+20+16共用体内でどの選択肢が選択されるかを制御する列挙型フィールドのオフセットです。 このフィールドのサイズは、列挙型のサイズ (32 ビット符号付き整数) であると想定されます。
noneEnumValueINT4+24+20この値は、いずれの選択肢も現在設定されていない場合に使用される列挙値に対応します。 このフィールドは、フィールドが省略可能である場合 (WS_FIELD_OPTIONAL が指定された場合) にのみ使用されます。
valueIndicesDWORD*8/4+32+24

この省略可能な配列は、共用体のフィールドを要素または列挙値によって検索する 際の性能を向上させることができる情報を提供します。この配列は NULL でもかまいません。 その場合は O(n) の検索が使用されますが、フィールド数が少なければ それで十分な場合もあります。

NULL 以外の場合は、次の条件を満たしていなければなりません。

  • fields 配列は、要素によって昇順に並べ替えられている必要があります。 要素を比較する際は、最初に名前空間を比較し、次にローカル名を比較します。 各名前は、utf-8 文字列のバイト単位の比較によって比較します。 WS_ANY_ELEMENT_FIELD_MAPPING を使用するフィールドが存在する場合、それは常に fields 配列の最後になければなりません。
  • valueIndices 配列は、fieldCount 個の項目を持つ配列を指します。valueIndices 配列は、fields 配列の項目を値によって昇順に並べ替えた場合のインデックスを 提供します。

公式ドキュメント

共用体型内の選択肢に関する情報です。 これは WS_UNION_TYPE で使用されます。

解説(Remarks)

この記述では、セレクター値 (整数の列挙値) と、可能な選択肢の それぞれに対応するフィールドを含む共用体の両方を持つ構造体を 想定しています。次に例を示します。

// Enumeration of choices of different values
enum Choice
{
    ChoiceA = 20,
    ChoiceB = 10,
    None = 0,
};

// Struct containing union of values, and enum "selector"
struct StructType
{
    Choice choice;
    union
    {
        int a;
        WS_STRING b;
    } value;
};

次の例は、前述の例に対する共用体の記述を初期化する方法を示しています。この例では nameIndices フィールドを設定していますが、このフィールドは代わりに NULL にすることもできます。

WS_XML_STRING choiceAString = WS_XML_STRING_VALUE("choiceA");
WS_XML_STRING choiceANs = WS_XML_STRING_VALUE("http://examples.org/a");

WS_UNION_FIELD_DESCRIPTION fieldA = { };
fieldA.value = ChoiceA;
fieldA.field.localName = &choiceAString;
fieldA.field.ns = &choiceANs;
fieldA.field.type = WS_INT32_TYPE;
fieldA.field.offset = WsOffsetOf(StructType, value.a);

WS_XML_STRING choiceBString = WS_XML_STRING_VALUE("choiceB");
WS_XML_STRING choiceBNs = WS_XML_STRING_VALUE("http://examples.org/b");

WS_UNION_FIELD_DESCRIPTION fieldB = { };
fieldB.value = ChoiceB;
fieldB.field.localName = &choiceBString;
fieldB.field.ns = &choiceBNs;
fieldB.field.type = WS_STRING_TYPE;
fieldB.field.offset = WsOffsetOf(StructType, value.b);

// Sorted by ascending element name (first ns, then localName)
WS_UNION_FIELD_DESCRIPTION* fieldsArray[] =
{
    &fieldA, // "http://example.com/a", "choiceA"
    &fieldB, // "http://example.com/b", "choiceB"
};

// Sorted by ascending enum value
ULONG valueIndices[] =
{
    1, // ChoiceB (10)
    0, // ChoiceA (20)
};

WS_UNION_DESCRIPTION unionDescription;
unionDescription.size = sizeof(StructType);
unionDescription.alignment = __alignof(StructType);
unionDescription.fields = fieldsArray;
unionDescription.fieldCount = WsCountOf(fieldsArray);
unionDescription.enumOffset = WsOffsetOf(StructType, choice);
unionDescription.noneEnumValue = None;
unionDescription.valueIndices = valueIndices;

上記により、次のいずれかの要素が出現できるようになります。

<choiceA xmlns="http://example.com/a">123</choiceA>
<choiceB xmlns="http://example.com/b">hello</choiceB>

次は、値を設定する例です。

StructType structType;

// Set ChoiceA
structType.choice = ChoiceA;
structType.value.a = 123;

// Set ChoiceB
static const WS_STRING = WS_STRING_VALUE(L"hello");
structType.choice = ChoiceB;
structType.value.b = helloString;

// Set "none" choice
structType.choice = None;

次は、WS_UNION_DESCRIPTION を構成する WS_FIELD_DESCRIPTION の順序を記述した文法です。順序は WS_FIELD_DESCRIPTION の mapping フィールドに基づいて定義されます。


Fields := ElementContentFields AnyElementField?
ElementContentFields := (ElementField | RepeatingElementField)*
ElementField := WS_ELEMENT_FIELD_MAPPING
RepeatingElementField := WS_REPEATING_ELEMENT_FIELD_MAPPING
AnyElementField := WS_ANY_ELEMENT_FIELD_MAPPING

WS_ELEMENT_FIELD_MAPPINGWS_REPEATING_ELEMENT_FIELD_MAPPING は、要素の選択肢と、共用体内の対応するフィールドを表します。

WS_ANY_ELEMENT_FIELD_MAPPING は、他のどの要素も一致しなかった場合に 使用されるフィールドです。

フィールドの記述には次の制限が適用されます。

出典・ライセンス: 上記「公式ドキュメント」の内容は Microsoft の Win32 API ドキュメント(MicrosoftDocs/sdk-api)を日本語に翻訳・改変したものです。© Microsoft Corporation. CC BY 4.0 で提供。
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)

各言語での定義

#include <windows.h>

// WS_UNION_DESCRIPTION  (x64 40 / x86 28 バイト)
typedef struct WS_UNION_DESCRIPTION {
    DWORD size;
    DWORD alignment;
    WS_UNION_FIELD_DESCRIPTION** fields;
    DWORD fieldCount;
    DWORD enumOffset;
    INT noneEnumValue;
    DWORD* valueIndices;
} WS_UNION_DESCRIPTION;
using System;
using System.Runtime.InteropServices;

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct WS_UNION_DESCRIPTION
{
    public uint size;
    public uint alignment;
    public IntPtr fields;
    public uint fieldCount;
    public uint enumOffset;
    public int noneEnumValue;
    public IntPtr valueIndices;
}
Imports System.Runtime.InteropServices

<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)>
Public Structure WS_UNION_DESCRIPTION
    Public size As UInteger
    Public alignment As UInteger
    Public fields As IntPtr
    Public fieldCount As UInteger
    Public enumOffset As UInteger
    Public noneEnumValue As Integer
    Public valueIndices As IntPtr
End Structure
import ctypes
from ctypes import wintypes

class WS_UNION_DESCRIPTION(ctypes.Structure):
    _fields_ = [
        ("size", wintypes.DWORD),
        ("alignment", wintypes.DWORD),
        ("fields", ctypes.c_void_p),
        ("fieldCount", wintypes.DWORD),
        ("enumOffset", wintypes.DWORD),
        ("noneEnumValue", ctypes.c_int),
        ("valueIndices", ctypes.c_void_p),
    ]
#[repr(C)]
pub struct WS_UNION_DESCRIPTION {
    pub size: u32,
    pub alignment: u32,
    pub fields: *mut core::ffi::c_void,
    pub fieldCount: u32,
    pub enumOffset: u32,
    pub noneEnumValue: i32,
    pub valueIndices: *mut core::ffi::c_void,
}
import "golang.org/x/sys/windows"

type WS_UNION_DESCRIPTION struct {
	size uint32
	alignment uint32
	fields uintptr
	fieldCount uint32
	enumOffset uint32
	noneEnumValue int32
	valueIndices uintptr
}
type
  WS_UNION_DESCRIPTION = record
    size: DWORD;
    alignment: DWORD;
    fields: Pointer;
    fieldCount: DWORD;
    enumOffset: DWORD;
    noneEnumValue: Integer;
    valueIndices: Pointer;
  end;
const WS_UNION_DESCRIPTION = extern struct {
    size: u32,
    alignment: u32,
    fields: ?*anyopaque,
    fieldCount: u32,
    enumOffset: u32,
    noneEnumValue: i32,
    valueIndices: ?*anyopaque,
};
type
  WS_UNION_DESCRIPTION {.bycopy.} = object
    size: uint32
    alignment: uint32
    fields: pointer
    fieldCount: uint32
    enumOffset: uint32
    noneEnumValue: int32
    valueIndices: pointer
struct WS_UNION_DESCRIPTION
{
    uint size;
    uint alignment;
    void* fields;
    uint fieldCount;
    uint enumOffset;
    int noneEnumValue;
    void* valueIndices;
}

HSP用 定義

HSP3.7/3.8 は構造体機能が無いため4byte整数配列(dim)+peek/poke で操作(32/64bitでサイズ・位置が異なる場合はタブで分割)。IronHSP は NSTRUCT(#defstruct/stdim/->)で32/64bit共通。

; HSP3.7/3.8 は構造体機能が無いため、4byte整数の配列変数で操作します。(x86 レイアウト)
; WS_UNION_DESCRIPTION サイズ: 28 バイト(x86)
dim st, 7    ; 4byte整数×7(構造体サイズ 28 / 4 切り上げ)
; size : DWORD (+0, 4byte)  st.0 = 値  /  値 = st.0   (lpoke/lpeek も可)
; alignment : DWORD (+4, 4byte)  st.1 = 値  /  値 = st.1   (lpoke/lpeek も可)
; fields : WS_UNION_FIELD_DESCRIPTION** (+8, 4byte)  varptr(st)+8 を基点に操作(4byte:入れ子/配列)
; fieldCount : DWORD (+12, 4byte)  st.3 = 値  /  値 = st.3   (lpoke/lpeek も可)
; enumOffset : DWORD (+16, 4byte)  st.4 = 値  /  値 = st.4   (lpoke/lpeek も可)
; noneEnumValue : INT (+20, 4byte)  st.5 = 値  /  値 = st.5   (lpoke/lpeek も可)
; valueIndices : DWORD* (+24, 4byte)  st.6 = 値  /  値 = st.6   (lpoke/lpeek も可)
; ※4byte境界の整数は添字 st.N(N=オフセット/4)で読み書き可。それ以外は peek/poke 系を使用。
; HSP3.7/3.8 は構造体機能が無いため、4byte整数の配列変数で操作します。(x64 レイアウト)
; WS_UNION_DESCRIPTION サイズ: 40 バイト(x64)
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_UNION_FIELD_DESCRIPTION** (+8, 8byte)  varptr(st)+8 を基点に操作(8byte:入れ子/配列)
; fieldCount : DWORD (+16, 4byte)  st.4 = 値  /  値 = st.4   (lpoke/lpeek も可)
; enumOffset : DWORD (+20, 4byte)  st.5 = 値  /  値 = st.5   (lpoke/lpeek も可)
; noneEnumValue : INT (+24, 4byte)  st.6 = 値  /  値 = st.6   (lpoke/lpeek も可)
; valueIndices : DWORD* (+32, 8byte)  qpoke st,32,値 / qpeek(st,32)  ※IronHSPのみ。3.7/3.8は lpoke st,32,下位 : lpoke st,36,上位
; ※4byte境界の整数は添字 st.N(N=オフセット/4)で読み書き可。それ以外は peek/poke 系を使用。
; IronHSP は NSTRUCT(構造体)をサポート。32bit/64bit どちらでも同じコードで動作します。
#defstruct global WS_UNION_DESCRIPTION
    #field int size
    #field int alignment
    #field intptr fields
    #field int fieldCount
    #field int enumOffset
    #field int noneEnumValue
    #field intptr valueIndices
#endstruct

stdim st, WS_UNION_DESCRIPTION        ; NSTRUCT 変数を確保
st->size = 100
mes "size=" + st->size