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

ADDRINFOW

構造体
サイズx64: 48 バイト / x86: 32 バイト

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

フィールド

フィールド型サイズx64x86説明
ai_flagsINT4+0+0

GetAddrInfoW 関数で使用されるオプションを示すフラグです。

ai_flags メンバーでサポートされる値は Winsock2.h ヘッダーファイルで定義されており、次の表に示すオプションを組み合わせて指定できます。

値 意味
AI_PASSIVE
0x01
ソケットアドレスは bind 関数の呼び出しで使用されます。
AI_CANONNAME
0x02
正規名が最初の ai_canonname メンバーに返されます。
AI_NUMERICHOST
0x04
GetAddrInfoW 関数に渡される nodename パラメーターは、数値形式の文字列でなければなりません。
AI_ALL
0x0100
このビットが設定されている場合、IPv6 アドレスの要求と、AI_V4MAPPED を伴う IPv4 アドレスの要求が行われます。

このオプションは Windows Vista 以降でサポートされます。

AI_ADDRCONFIG
0x0400
GetAddrInfoW は、グローバルアドレスが構成されている場合にのみ名前解決を行います。IPv6 および IPv4 のループバックアドレスは、有効なグローバルアドレスとは見なされません。このオプションは Windows Vista 以降でのみサポートされます。
AI_V4MAPPED
0x0800
GetAddrInfoW による IPv6 アドレスの要求が失敗した場合、IPv4 アドレスに対する名前サービス要求が行われ、取得されたアドレスは IPv4 射影 IPv6 アドレス形式に変換されます。

このオプションは Windows Vista 以降でサポートされます。

AI_NON_AUTHORITATIVE
0x04000
アドレス情報は、権威のない名前空間プロバイダーから取得されたものでもかまいません。

このオプションは、NS_EMAIL 名前空間に対して Windows Vista 以降でのみサポートされます。

AI_SECURE
0x08000
アドレス情報は、セキュリティで保護されたチャネルから取得されます。

このオプションは、NS_EMAIL 名前空間に対して Windows Vista 以降でのみサポートされます。

AI_RETURN_PREFERRED_NAMES
0x010000
アドレス情報は、ユーザーの優先名に関するものです。

このオプションは、NS_EMAIL 名前空間に対して Windows Vista 以降でのみサポートされます。

AI_FQDN
0x00020000
フラットな名前 (単一ラベル) が指定された場合、GetAddrInfoW は、その名前が最終的に解決された完全修飾ドメイン名を返します。完全修飾ドメイン名は ai_canonname メンバーに返されます。

これは、DNS に登録された正規名を返す AI_CANONNAME ビットフラグとは異なります。正規名は、フラットな名前が解決された完全修飾ドメイン名とは異なる場合があります。

AI_FQDN と AI_CANONNAME のビットは、どちらか一方しか設定できません。両方のフラグが指定された場合、GetAddrInfoW 関数は EAI_BADFLAGS で失敗します。

このオプションは Windows 7、Windows Server 2008 R2 以降でサポートされます。

AI_FILESERVER
0x00040000
照会されているホスト名がファイル共有のシナリオで使用されていることを名前空間プロバイダーに知らせるヒントです。名前空間プロバイダーはこのヒントを無視する場合があります。

このオプションは Windows 7、Windows Server 2008 R2 以降でサポートされます。

AI_DISABLE_IDN_ENCODING
0x00080000
GetAddrInfoW 関数から呼び出される名前解決関数において、Punycode を使用した国際化ドメイン名の自動エンコードを無効にします。

このオプションは Windows 8、Windows Server 2012 以降でサポートされます。

ai_familyINT4+4+4

アドレスファミリです。アドレスファミリに指定できる値は Winsock2.h ヘッダーファイルで定義されています。

Windows Vista 以降向けにリリースされた Windows SDK では、ヘッダーファイルの構成が変更され、アドレスファミリに指定できる値は Ws2def.h ヘッダーファイルで定義されています。Ws2def.h ヘッダーファイルは Winsock2.h に自動的にインクルードされるため、直接使用しないでください。

現在サポートされている値は AF_INET または AF_INET6 で、これらはそれぞれ IPv4 と IPv6 のインターネットアドレスファミリ形式です。その他のアドレスファミリ (たとえば NetBIOS で使用する AF_NETBIOS) も、そのアドレスファミリ用の Windows ソケットサービスプロバイダーがインストールされていればサポートされます。AF_ アドレスファミリ定数と PF_ プロトコルファミリ定数の値は同一である (たとえば AF_UNSPEC と PF_UNSPEC) ため、どちらの定数も使用できます。

次の表は、アドレスファミリの代表的な値を示しています。ここに挙げた以外にも多くの値を指定できます。

値 意味
AF_UNSPEC
0
アドレスファミリは未指定です。
AF_INET
2
インターネットプロトコルバージョン 4 (IPv4) のアドレスファミリです。
AF_NETBIOS
17
NetBIOS のアドレスファミリです。このアドレスファミリは、NetBIOS 用の Windows ソケットプロバイダーがインストールされている場合にのみサポートされます。
AF_INET6
23
インターネットプロトコルバージョン 6 (IPv6) のアドレスファミリです。
AF_IRDA
26
Infrared Data Association (IrDA) のアドレスファミリです。このアドレスファミリは、コンピューターに赤外線ポートとドライバーがインストールされている場合にのみサポートされます。
AF_BTH
32
Bluetooth のアドレスファミリです。このアドレスファミリは、Windows Server 2003 以降で Bluetooth アダプターがインストールされている場合にのみサポートされます。
ai_socktypeINT4+8+8

ソケットの種類です。ソケットの種類に指定できる値は Winsock2.h インクルードファイルで定義されています。

次の表は、Windows Sockets 2 でサポートされるソケットの種類の値を示しています。

値 意味
SOCK_STREAM
1
順序が保証された、信頼性のある双方向の接続型バイトストリームを、OOB データ送信機構とともに提供します。インターネットアドレスファミリ (AF_INET または AF_INET6) では、伝送制御プロトコル (TCP) を使用します。ai_family メンバーが AF_IRDA の場合、サポートされるソケットの種類は SOCK_STREAM のみです。
SOCK_DGRAM
2
データグラムをサポートします。データグラムは、コネクションレスで信頼性のない、固定 (通常は小さい) の最大長を持つバッファーです。インターネットアドレスファミリ (AF_INET または AF_INET6) では、ユーザーデータグラムプロトコル (UDP) を使用します。
SOCK_RAW
3
アプリケーションが 1 つ上位層のプロトコルヘッダーを操作できる raw ソケットを提供します。IPv4 ヘッダーを操作するには、ソケットに IP_HDRINCL ソケットオプションを設定する必要があります。IPv6 ヘッダーを操作するには、ソケットに IPV6_HDRINCL ソケットオプションを設定する必要があります。
SOCK_RDM
4
信頼性のあるメッセージデータグラムを提供します。この種類の例としては、Windows における Pragmatic General Multicast (PGM) マルチキャストプロトコルの実装があり、一般に 信頼性のあるマルチキャストプログラミング と呼ばれます。
SOCK_SEQPACKET
5
データグラムに基づく擬似ストリームパケットを提供します。

Windows Sockets 2 では、新しいソケットの種類が導入されました。アプリケーションは、 WSAEnumProtocols 関数を使用して、利用可能な各トランスポートプロトコルの属性を動的に取得できます。これにより、アプリケーションはアドレスファミリごとに指定可能なソケットの種類とプロトコルのオプションを判別し、その情報をこのパラメーターの指定に利用できます。Winsock2.h および Ws2def.h ヘッダーファイル内のソケットの種類の定義は、新しいソケットの種類、アドレスファミリ、プロトコルが定義されるたびに随時更新されます。

Windows Sockets 1.1 では、指定できるソケットの種類は SOCK_DATAGRAM と SOCK_STREAM のみです。

ai_protocolINT4+12+12

プロトコルの種類です。指定できるオプションは、指定したアドレスファミリとソケットの種類に依存します。ai_protocol に指定できる値は、Winsock2.h および Wsrm.h ヘッダーファイルで定義されています。

Windows Vista 以降向けにリリースされた Windows SDK では、ヘッダーファイルの構成が変更され、このメンバーには Ws2def.h ヘッダーファイルで定義されている IPPROTO 列挙型の値のいずれかを指定できます。Ws2def.h ヘッダーファイルは Winsock2.h に自動的にインクルードされるため、直接使用しないでください。

ai_protocol に 0 を指定した場合、呼び出し元はプロトコルの指定を行わず、サービスプロバイダーが使用する ai_protocol を選択します。IPv4 と IPv6 以外のプロトコルでは、ai_protocol に 0 を設定します。

次の表は、ai_protocol メンバーの代表的な値を示しています。ここに挙げた以外にも多くの値を指定できます。

値 意味
IPPROTO_TCP
6
伝送制御プロトコル (TCP) です。これは、ai_family メンバーが AF_INET または AF_INET6 で、ai_socktype メンバーが SOCK_STREAM の場合に指定できる値です。
IPPROTO_UDP
17
ユーザーデータグラムプロトコル (UDP) です。これは、ai_family メンバーが AF_INET または AF_INET6 で、type パラメーターが SOCK_DGRAM の場合に指定できる値です。
IPPROTO_RM
113
信頼性のあるマルチキャストのための PGM プロトコルです。これは、ai_family メンバーが AF_INET で、ai_socktype メンバーが SOCK_RDM の場合に指定できる値です。Windows Vista 以降向けにリリースされた Windows SDK では、この値は IPPROTO_PGM とも呼ばれます。

ai_family メンバーが AF_IRDA の場合、ai_protocol は 0 でなければなりません。

ai_addrlenUINT_PTR8/4+16+16ai_addr メンバーが指すバッファーの長さ (バイト単位) です。
ai_canonnameLPWSTR8/4+24+20ホストの正規名です。
ai_addrSOCKADDR*8/4+32+24sockaddr 構造体へのポインターです。返される各 ADDRINFOW 構造体の ai_addr メンバーは、値が設定されたソケットアドレス構造体を指します。返される各 ADDRINFOW 構造体の長さ (バイト単位) は、ai_addrlen メンバーで示されます。
ai_nextADDRINFOW*8/4+40+28リンクリスト内の次の構造体へのポインターです。このパラメーターは、リンクリストの最後の addrinfoW 構造体では NULL に設定されます。

公式ドキュメント

addrinfoW 構造体は、 GetAddrInfoW 関数がホストのアドレス情報を保持するために使用します。

解説(Remarks)

addrinfoW 構造体は、 Unicode 版の GetAddrInfoW 関数がホストのアドレス情報を保持するために使用します。

addrinfo 構造体は、ANSI 版の getaddrinfo 関数が使用する、この構造体の ANSI 版です。

Ws2tcpip.h ヘッダーファイル内のマクロにより、ADDRINFOT 構造体と、大文字小文字が混在する名前の関数 GetAddrInfo が定義されています。GetAddrInfo 関数は、nodename と servname パラメーターに TCHAR 型のポインターを、hints と res パラメーターに ADDRINFOT 型のポインターを指定して呼び出します。UNICODE または _UNICODE が定義されている場合、ADDRINFOT は addrinfoW 構造体として定義され、GetAddrInfo はこの関数の Unicode 版である GetAddrInfoW として定義されます。UNICODE も _UNICODE も定義されていない場合、ADDRINFOT は addrinfo 構造体として定義され、GetAddrInfo はこの関数の ANSI 版である getaddrinfo として定義されます。

GetAddrInfoW の呼び出しが成功すると、 ADDRINFOW 構造体のリンクリストが、GetAddrInfoW 関数に渡した ppResult パラメーターに返されます。このリストは、返された各 ADDRINFOW 構造体の ai_next メンバーが示すポインターを、NULL ポインターに到達するまでたどることで処理できます。返される各 ADDRINFOW 構造体において、ai_family、ai_socktype、ai_protocol の各メンバーは、 socket 関数または WSASocket 関数の呼び出しにおける対応する引数に相当します。また、返される各 ADDRINFOW 構造体の ai_addr メンバーは、値が設定されたソケットアドレス構造体を指し、その長さは同じ構造体の ai_addrlen メンバーで示されます。

例

次のコード例は、addrinfoW 構造体の使用方法を示しています。

#ifndef UNICODE
#define UNICODE
#endif

#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif

#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>

#pragma comment(lib, "Ws2_32.lib")

int __cdecl wmain(int argc, wchar_t ** argv)
{
//--------------------------------
// Declare and initialize variables.
    WSADATA wsaData;
    int iResult;

    ADDRINFOW *result = NULL;
    ADDRINFOW *ptr = NULL;
    ADDRINFOW hints;

    DWORD dwRetval = 0;
    int i = 1;

    struct sockaddr_in *sockaddr_ipv4;
    struct sockaddr_in6 *sockaddr_ipv6;
//    LPSOCKADDR sockaddr_ip;

    wchar_t ipstringbuffer[46];

    // Validate the parameters
    if (argc != 3) {
        wprintf(L"usage: %ws <hostname> <servicename>\n", argv[0]);
        wprintf(L"       provides protocol-independent translation\n");
        wprintf(L"       from a host name to an IP address\n");
        wprintf(L"%ws example usage\n", argv[0]);
        wprintf(L"   %ws www.contoso.com 0\n", argv[0]);
        return 1;
    }
    // Initialize Winsock
    iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
    if (iResult != 0) {
        wprintf(L"WSAStartup failed: %d\n", iResult);
        return 1;
    }
//--------------------------------
// Setup the hints address info structure
// which is passed to the GetAddrInfoW() function
    memset(&hints, 0, sizeof (hints));
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP;

    wprintf(L"Calling GetAddrInfoW with following parameters:\n");
    wprintf(L"\tName = %ws\n", argv[1]);
    wprintf(L"\tServiceName (or port) = %ws\n\n", argv[2]);

//--------------------------------
// Call GetAddrInfoW(). If the call succeeds,
// the aiList variable will hold a linked list
// of addrinfo structures containing response
// information about the host
    dwRetval = GetAddrInfoW(argv[1], argv[2], &hints, &result);

    if (dwRetval != 0) {
        wprintf(L"GetAddrInfoW failed with error: %d\n", dwRetval);
        WSACleanup();
        return 1;
    }
    wprintf(L"GetAddrInfoW returned success\n");

    // Retrieve each address and print out the hex bytes
    for (ptr = result; ptr != NULL; ptr = ptr->ai_next) {

        wprintf(L"GetAddrInfoW response %d\n", i++);
        wprintf(L"\tFlags: 0x%x\n", ptr->ai_flags);
        wprintf(L"\tFamily: ");
        switch (ptr->ai_family) {
        case AF_UNSPEC:
            wprintf(L"Unspecified\n");
            break;
        case AF_INET:
            wprintf(L"AF_INET (IPv4)\n");
            // the InetNtop function is available on Windows Vista and later
            sockaddr_ipv4 = (struct sockaddr_in *) ptr->ai_addr;
            wprintf(L"\tIPv4 address %ws\n",
                    InetNtop(AF_INET, &sockaddr_ipv4->sin_addr, ipstringbuffer,
                             46));

            // We could also use the WSAAddressToString function
            // sockaddr_ip = (LPSOCKADDR) ptr->ai_addr;
            // The buffer length is changed by each call to WSAAddresstoString
            // So we need to set it for each iteration through the loop for safety
            // ipbufferlength = 46;
            // iRetval = WSAAddressToString(sockaddr_ip, (DWORD) ptr->ai_addrlen, NULL, 
            //    ipstringbuffer, &ipbufferlength );
            // if (iRetval)
            //    wprintf(L"WSAAddressToString failed with %u\n", WSAGetLastError() );
            // else    
            //    wprintf(L"\tIPv4 address %ws\n", ipstringbuffer);
            break;
        case AF_INET6:
            wprintf(L"AF_INET6 (IPv6)\n");
            // the InetNtop function is available on Windows Vista and later
            sockaddr_ipv6 = (struct sockaddr_in6 *) ptr->ai_addr;
            wprintf(L"\tIPv6 address %ws\n",
                    InetNtop(AF_INET6, &sockaddr_ipv6->sin6_addr,
                             ipstringbuffer, 46));

            // We could also use WSAAddressToString which also returns the scope ID
            // sockaddr_ip = (LPSOCKADDR) ptr->ai_addr;
            // The buffer length is changed by each call to WSAAddresstoString
            // So we need to set it for each iteration through the loop for safety
            // ipbufferlength = 46;
            //iRetval = WSAAddressToString(sockaddr_ip, (DWORD) ptr->ai_addrlen, NULL, 
            //    ipstringbuffer, &ipbufferlength );
            //if (iRetval)
            //    wprintf(L"WSAAddressToString failed with %u\n", WSAGetLastError() );
            //else    
            //    wprintf(L"\tIPv6 address %ws\n", ipstringbuffer);
            break;
        default:
            wprintf(L"Other %ld\n", ptr->ai_family);
            break;
        }
        wprintf(L"\tSocket type: ");
        switch (ptr->ai_socktype) {
        case 0:
            wprintf(L"Unspecified\n");
            break;
        case SOCK_STREAM:
            wprintf(L"SOCK_STREAM (stream)\n");
            break;
        case SOCK_DGRAM:
            wprintf(L"SOCK_DGRAM (datagram) \n");
            break;
        case SOCK_RAW:
            wprintf(L"SOCK_RAW (raw) \n");
            break;
        case SOCK_RDM:
            wprintf(L"SOCK_RDM (reliable message datagram)\n");
            break;
        case SOCK_SEQPACKET:
            wprintf(L"SOCK_SEQPACKET (pseudo-stream packet)\n");
            break;
        default:
            wprintf(L"Other %ld\n", ptr->ai_socktype);
            break;
        }
        wprintf(L"\tProtocol: ");
        switch (ptr->ai_protocol) {
        case 0:
            wprintf(L"Unspecified\n");
            break;
        case IPPROTO_TCP:
            wprintf(L"IPPROTO_TCP (TCP)\n");
            break;
        case IPPROTO_UDP:
            wprintf(L"IPPROTO_UDP (UDP) \n");
            break;
        default:
            wprintf(L"Other %ld\n", ptr->ai_protocol);
            break;
        }
        wprintf(L"\tLength of this sockaddr: %d\n", ptr->ai_addrlen);
        wprintf(L"\tCanonical name: %s\n", ptr->ai_canonname);
    }

    FreeAddrInfo(result);
    WSACleanup();

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

各言語での定義

#include <windows.h>

// ADDRINFOW  (x64 48 / x86 32 バイト)
typedef struct ADDRINFOW {
    INT ai_flags;
    INT ai_family;
    INT ai_socktype;
    INT ai_protocol;
    UINT_PTR ai_addrlen;
    LPWSTR ai_canonname;
    SOCKADDR* ai_addr;
    ADDRINFOW* ai_next;
} ADDRINFOW;
using System;
using System.Runtime.InteropServices;

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct ADDRINFOW
{
    public int ai_flags;
    public int ai_family;
    public int ai_socktype;
    public int ai_protocol;
    public UIntPtr ai_addrlen;
    public IntPtr ai_canonname;
    public IntPtr ai_addr;
    public IntPtr ai_next;
}
Imports System.Runtime.InteropServices

<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)>
Public Structure ADDRINFOW
    Public ai_flags As Integer
    Public ai_family As Integer
    Public ai_socktype As Integer
    Public ai_protocol As Integer
    Public ai_addrlen As UIntPtr
    Public ai_canonname As IntPtr
    Public ai_addr As IntPtr
    Public ai_next As IntPtr
End Structure
import ctypes
from ctypes import wintypes

class ADDRINFOW(ctypes.Structure):
    _fields_ = [
        ("ai_flags", ctypes.c_int),
        ("ai_family", ctypes.c_int),
        ("ai_socktype", ctypes.c_int),
        ("ai_protocol", ctypes.c_int),
        ("ai_addrlen", ctypes.c_size_t),
        ("ai_canonname", ctypes.c_void_p),
        ("ai_addr", ctypes.c_void_p),
        ("ai_next", ctypes.c_void_p),
    ]
#[repr(C)]
pub struct ADDRINFOW {
    pub ai_flags: i32,
    pub ai_family: i32,
    pub ai_socktype: i32,
    pub ai_protocol: i32,
    pub ai_addrlen: usize,
    pub ai_canonname: *mut core::ffi::c_void,
    pub ai_addr: *mut core::ffi::c_void,
    pub ai_next: *mut core::ffi::c_void,
}
import "golang.org/x/sys/windows"

type ADDRINFOW struct {
	ai_flags int32
	ai_family int32
	ai_socktype int32
	ai_protocol int32
	ai_addrlen uintptr
	ai_canonname uintptr
	ai_addr uintptr
	ai_next uintptr
}
type
  ADDRINFOW = record
    ai_flags: Integer;
    ai_family: Integer;
    ai_socktype: Integer;
    ai_protocol: Integer;
    ai_addrlen: NativeUInt;
    ai_canonname: Pointer;
    ai_addr: Pointer;
    ai_next: Pointer;
  end;
const ADDRINFOW = extern struct {
    ai_flags: i32,
    ai_family: i32,
    ai_socktype: i32,
    ai_protocol: i32,
    ai_addrlen: usize,
    ai_canonname: ?*anyopaque,
    ai_addr: ?*anyopaque,
    ai_next: ?*anyopaque,
};
type
  ADDRINFOW {.bycopy.} = object
    ai_flags: int32
    ai_family: int32
    ai_socktype: int32
    ai_protocol: int32
    ai_addrlen: uint
    ai_canonname: pointer
    ai_addr: pointer
    ai_next: pointer
struct ADDRINFOW
{
    int ai_flags;
    int ai_family;
    int ai_socktype;
    int ai_protocol;
    size_t ai_addrlen;
    void* ai_canonname;
    void* ai_addr;
    void* ai_next;
}

HSP用 定義

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

; HSP3.7/3.8 は構造体機能が無いため、4byte整数の配列変数で操作します。(x86 レイアウト)
; ADDRINFOW サイズ: 32 バイト(x86)
dim st, 8    ; 4byte整数×8(構造体サイズ 32 / 4 切り上げ)
; ai_flags : INT (+0, 4byte)  st.0 = 値  /  値 = st.0   (lpoke/lpeek も可)
; ai_family : INT (+4, 4byte)  st.1 = 値  /  値 = st.1   (lpoke/lpeek も可)
; ai_socktype : INT (+8, 4byte)  st.2 = 値  /  値 = st.2   (lpoke/lpeek も可)
; ai_protocol : INT (+12, 4byte)  st.3 = 値  /  値 = st.3   (lpoke/lpeek も可)
; ai_addrlen : UINT_PTR (+16, 4byte)  st.4 = 値  /  値 = st.4   (lpoke/lpeek も可)
; ai_canonname : LPWSTR (+20, 4byte)  st.5 = 値  /  値 = st.5   (lpoke/lpeek も可)
; ai_addr : SOCKADDR* (+24, 4byte)  varptr(st)+24 を基点に操作(4byte:入れ子/配列)
; ai_next : ADDRINFOW* (+28, 4byte)  varptr(st)+28 を基点に操作(4byte:入れ子/配列)
; ※4byte境界の整数は添字 st.N(N=オフセット/4)で読み書き可。それ以外は peek/poke 系を使用。
; HSP3.7/3.8 は構造体機能が無いため、4byte整数の配列変数で操作します。(x64 レイアウト)
; ADDRINFOW サイズ: 48 バイト(x64)
dim st, 12    ; 4byte整数×12(構造体サイズ 48 / 4 切り上げ)
; ai_flags : INT (+0, 4byte)  st.0 = 値  /  値 = st.0   (lpoke/lpeek も可)
; ai_family : INT (+4, 4byte)  st.1 = 値  /  値 = st.1   (lpoke/lpeek も可)
; ai_socktype : INT (+8, 4byte)  st.2 = 値  /  値 = st.2   (lpoke/lpeek も可)
; ai_protocol : INT (+12, 4byte)  st.3 = 値  /  値 = st.3   (lpoke/lpeek も可)
; ai_addrlen : UINT_PTR (+16, 8byte)  qpoke st,16,値 / qpeek(st,16)  ※IronHSPのみ。3.7/3.8は lpoke st,16,下位 : lpoke st,20,上位
; ai_canonname : LPWSTR (+24, 8byte)  qpoke st,24,値 / qpeek(st,24)  ※IronHSPのみ。3.7/3.8は lpoke st,24,下位 : lpoke st,28,上位
; ai_addr : SOCKADDR* (+32, 8byte)  varptr(st)+32 を基点に操作(8byte:入れ子/配列)
; ai_next : ADDRINFOW* (+40, 8byte)  varptr(st)+40 を基点に操作(8byte:入れ子/配列)
; ※4byte境界の整数は添字 st.N(N=オフセット/4)で読み書き可。それ以外は peek/poke 系を使用。
; IronHSP は NSTRUCT(構造体)をサポート。32bit/64bit どちらでも同じコードで動作します。
#defstruct global ADDRINFOW
    #field int ai_flags
    #field int ai_family
    #field int ai_socktype
    #field int ai_protocol
    #field intptr ai_addrlen
    #field intptr ai_canonname
    #field intptr ai_addr
    #field intptr ai_next
#endstruct

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