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

ADDRINFOA

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

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

フィールド

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

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

ai_flags メンバーでサポートされる値は、Windows 7 以降の Windows SDK では Ws2def.h ヘッダーファイルで定義されています。Windows Server 2008 および Windows Vista の Windows SDK では、これらの値は Ws2tcpip.h ヘッダーファイルで定義されています。Windows Server 2003 および Windows XP の Platform SDK では、これらの値は Ws2tcpip.h ヘッダーファイルで定義されています。ai_flags メンバーでサポートされる値には、次のオプションを組み合わせて指定できます。

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

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

AI_ADDRCONFIG
0x0400
getaddrinfo は、グローバルアドレスが構成されている場合にのみ名前を解決します。IPv6 および IPv4 のループバックアドレスは、有効なグローバルアドレスとは見なされません。

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

AI_V4MAPPED
0x0800
IPv6 アドレスに対する getaddrinfo の要求が失敗した場合、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
アドレス情報は、ユーザーの優先名 (preferred name) に関するものです。

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

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

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

AI_FQDNAI_CANONNAME のビットは、どちらか一方しか設定できません。両方のフラグが指定されている場合、getaddrinfo 関数は EAI_BADFLAGS で失敗します。

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

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

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

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_UNSPECPF_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_DATAGRAMSOCK_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_canonnameLPSTR8/4+24+20ホストの正規名です。
ai_addrSOCKADDR*8/4+32+24sockaddr 構造体へのポインターです。返される各 addrinfo 構造体の ai_addr メンバーは、値が設定されたソケットアドレス構造体を指します。返される各 addrinfo 構造体におけるその長さ (バイト単位) は、ai_addrlen メンバーで示されます。
ai_nextADDRINFOA*8/4+40+28リンクリスト内の次の構造体へのポインターです。リンクリストの最後の addrinfo 構造体では、このパラメーターは NULL に設定されます。

公式ドキュメント

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

解説(Remarks)

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

addrinfoW 構造体は、Unicode 版の GetAddrInfoW 関数で使用される、この構造体のバージョンです。

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

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

旧バージョンの Windows における getaddrinfo と addrinfo 構造体のサポート

addrinfo 構造体を使用する getaddrinfo 関数は、Windows XP 以降の Ws2_32.dll に追加されました。addrinfo 構造体は、Windows XP 以降向けにリリースされた Platform SDK、および Windows Vista 以降向けにリリースされた Windows SDK に含まれる Ws2tcpip.h ヘッダーファイルで定義されています。

getaddrinfo 関数と addrinfo 構造体を使用するアプリケーションをそれ以前のバージョンの Windows (Windows 2000) で実行するには、Ws2tcpip.hWspiapi.h をインクルードする必要があります。Wspiapi.h インクルードファイルを追加すると、getaddrinfo 関数は Wspiapi.h 内のインライン関数 WspiapiGetAddrInfo として定義されます。実行時には、Ws2_32.dll または Wship6.dll (Windows 2000 用 IPv6 Technology Preview で getaddrinfo を含むファイル) が getaddrinfo を提供していない場合に、Wspiapi.h ヘッダーファイル内のコードに基づく getaddrinfo の実装がインラインで使用されるように WspiapiGetAddrInfo 関数が実装されています。このインラインコードは、getaddrinfo 関数をネイティブにサポートしていない旧来の Windows プラットフォームで使用されます。

IPv6 プロトコルは、Windows 2000 用 IPv6 Technology Preview がインストールされている場合に Windows 2000 でサポートされます。それ以外の場合、Windows XP より前のバージョンの Windows における getaddrinfo のサポートは、IPv4 の名前解決の処理に限られます。

addrinfoW 構造体を使用する GetAddrInfoW 関数は、getaddrinfo 関数および対応する addrinfo 構造体の Unicode 版です。GetAddrInfoW 関数は、Windows XP Service Pack 2 (SP2) で Ws2_32.dll に追加されました。GetAddrInfoW 関数と addrinfoW 構造体は、Windows XP SP2 より前のバージョンの Windows では使用できません。

Examples

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


#undef UNICODE

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

// link with Ws2_32.lib
#pragma comment(lib, "Ws2_32.lib")

int __cdecl main(int argc, char **argv)
{

    //-----------------------------------------
    // Declare and initialize variables
    WSADATA wsaData;
    int iResult;
    INT iRetval;

    DWORD dwRetval;

    int i = 1;
    
    struct addrinfo *result = NULL;
    struct addrinfo *ptr = NULL;
    struct addrinfo hints;

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

    char ipstringbuffer[46];
    DWORD ipbufferlength = 46;

    // Validate the parameters
    if (argc != 3) {
        printf("usage: %s <hostname> <servicename>\n", argv[0]);
        printf("       provides protocol-independent translation\n");
        printf("       from an ANSI host name to an IP address\n");
        printf("%s example usage\n", argv[0]);
        printf("   %s www.contoso.com 0\n", argv[0]);
        return 1;
    }

    // Initialize Winsock
    iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
    if (iResult != 0) {
        printf("WSAStartup failed: %d\n", iResult);
        return 1;
    }

    //--------------------------------
    // Setup the hints address info structure
    // which is passed to the getaddrinfo() function
    ZeroMemory( &hints, sizeof(hints) );
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP;

    printf("Calling getaddrinfo with following parameters:\n");
    printf("\tnodename = %s\n", argv[1]);
    printf("\tservname (or port) = %s\n\n", argv[2]);
    
//--------------------------------
// Call getaddrinfo(). If the call succeeds,
// the result variable will hold a linked list
// of addrinfo structures containing response
// information
    dwRetval = getaddrinfo(argv[1], argv[2], &hints, &result);
    if ( dwRetval != 0 ) {
        printf("getaddrinfo failed with error: %d\n", dwRetval);
        WSACleanup();
        return 1;
    }

    printf("getaddrinfo returned success\n");
    
    // Retrieve each address and print out the hex bytes
    for(ptr=result; ptr != NULL ;ptr=ptr->ai_next) {

        printf("getaddrinfo response %d\n", i++);
        printf("\tFlags: 0x%x\n", ptr->ai_flags);
        printf("\tFamily: ");
        switch (ptr->ai_family) {
            case AF_UNSPEC:
                printf("Unspecified\n");
                break;
            case AF_INET:
                printf("AF_INET (IPv4)\n");
                sockaddr_ipv4 = (struct sockaddr_in *) ptr->ai_addr;
                printf("\tIPv4 address %s\n",
                    inet_ntoa(sockaddr_ipv4->sin_addr) );
                break;
            case AF_INET6:
                printf("AF_INET6 (IPv6)\n");
                // the InetNtop function is available on Windows Vista and later
                // sockaddr_ipv6 = (struct sockaddr_in6 *) ptr->ai_addr;
                // printf("\tIPv6 address %s\n",
                //    InetNtop(AF_INET6, &sockaddr_ipv6->sin6_addr, ipstringbuffer, 46) );
                
                // We use WSAAddressToString since it is supported on Windows XP and later
                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)
                    printf("WSAAddressToString failed with %u\n", WSAGetLastError() );
                else    
                    printf("\tIPv6 address %s\n", ipstringbuffer);
                break;
            case AF_NETBIOS:
                printf("AF_NETBIOS (NetBIOS)\n");
                break;
            default:
                printf("Other %ld\n", ptr->ai_family);
                break;
        }
        printf("\tSocket type: ");
        switch (ptr->ai_socktype) {
            case 0:
                printf("Unspecified\n");
                break;
            case SOCK_STREAM:
                printf("SOCK_STREAM (stream)\n");
                break;
            case SOCK_DGRAM:
                printf("SOCK_DGRAM (datagram) \n");
                break;
            case SOCK_RAW:
                printf("SOCK_RAW (raw) \n");
                break;
            case SOCK_RDM:
                printf("SOCK_RDM (reliable message datagram)\n");
                break;
            case SOCK_SEQPACKET:
                printf("SOCK_SEQPACKET (pseudo-stream packet)\n");
                break;
            default:
                printf("Other %ld\n", ptr->ai_socktype);
                break;
        }
        printf("\tProtocol: ");
        switch (ptr->ai_protocol) {
            case 0:
                printf("Unspecified\n");
                break;
            case IPPROTO_TCP:
                printf("IPPROTO_TCP (TCP)\n");
                break;
            case IPPROTO_UDP:
                printf("IPPROTO_UDP (UDP) \n");
                break;
            default:
                printf("Other %ld\n", ptr->ai_protocol);
                break;
        }
        printf("\tLength of this sockaddr: %d\n", ptr->ai_addrlen);
        printf("\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>

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

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct ADDRINFOA
{
    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 ADDRINFOA
    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 ADDRINFOA(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 ADDRINFOA {
    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 ADDRINFOA 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
  ADDRINFOA = 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 ADDRINFOA = 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
  ADDRINFOA {.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 ADDRINFOA
{
    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 レイアウト)
; ADDRINFOA サイズ: 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 : LPSTR (+20, 4byte)  st.5 = 値  /  値 = st.5   (lpoke/lpeek も可)
; ai_addr : SOCKADDR* (+24, 4byte)  varptr(st)+24 を基点に操作(4byte:入れ子/配列)
; ai_next : ADDRINFOA* (+28, 4byte)  varptr(st)+28 を基点に操作(4byte:入れ子/配列)
; ※4byte境界の整数は添字 st.N(N=オフセット/4)で読み書き可。それ以外は peek/poke 系を使用。
; HSP3.7/3.8 は構造体機能が無いため、4byte整数の配列変数で操作します。(x64 レイアウト)
; ADDRINFOA サイズ: 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 : LPSTR (+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 : ADDRINFOA* (+40, 8byte)  varptr(st)+40 を基点に操作(8byte:入れ子/配列)
; ※4byte境界の整数は添字 st.N(N=オフセット/4)で読み書き可。それ以外は peek/poke 系を使用。
; IronHSP は NSTRUCT(構造体)をサポート。32bit/64bit どちらでも同じコードで動作します。
#defstruct global ADDRINFOA
    #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, ADDRINFOA        ; NSTRUCT 変数を確保
st->ai_flags = 100
mes "ai_flags=" + st->ai_flags