Win32 API 日本語リファレンス
ホームNetworkManagement.IpHelper › GetAdaptersAddresses

GetAdaptersAddresses

関数
アダプターのIPアドレス等の詳細情報を取得する。
DLLIPHLPAPI.dll呼出規約winapi対応OSWindows XP 以降

シグネチャ

// IPHLPAPI.dll
#include <windows.h>

DWORD GetAdaptersAddresses(
    DWORD Family,
    GET_ADAPTERS_ADDRESSES_FLAGS Flags,
    void* Reserved,   // optional
    IP_ADAPTER_ADDRESSES_LH* AdapterAddresses,   // optional
    DWORD* SizePointer
);

パラメーター

名前方向説明
FamilyDWORDin

取得するアドレスのアドレスファミリです。このパラメーターは次のいずれかの値でなければなりません。

意味
AF_UNSPEC
0
IPv4 または IPv6 が有効なアダプターに関連付けられた IPv4 および IPv6 の両方のアドレスを返します。
AF_INET
2
IPv4 が有効なアダプターに関連付けられた IPv4 アドレスのみを返します。
AF_INET6
23
IPv6 が有効なアダプターに関連付けられた IPv6 アドレスのみを返します。
FlagsGET_ADAPTERS_ADDRESSES_FLAGSin

取得するアドレスの種類です。指定可能な値は Iptypes.h ヘッダーファイルで定義されています。なお、Iptypes.h ヘッダーファイルは Iphlpapi.h に自動的にインクルードされるため、直接使用してはなりません。

このパラメーターは次の値の組み合わせです。このパラメーターが 0 の場合、ユニキャスト、エニーキャスト、マルチキャストの IP アドレスが返されます。

意味
GAA_FLAG_SKIP_UNICAST
0x0001
ユニキャストアドレスを返しません。
GAA_FLAG_SKIP_ANYCAST
0x0002
IPv6 エニーキャストアドレスを返しません。
GAA_FLAG_SKIP_MULTICAST
0x0004
マルチキャストアドレスを返しません。
GAA_FLAG_SKIP_DNS_SERVER
0x0008
DNS サーバーのアドレスを返しません。
GAA_FLAG_INCLUDE_PREFIX
0x0010
このアダプター上の IP アドレスプレフィックスの一覧を返します。このフラグが設定されている場合、IPv6 と IPv4 の両方のアドレスについて IP アドレスプレフィックスが返されます。

このフラグは Windows XP with SP1 以降でサポートされています。

GAA_FLAG_SKIP_FRIENDLY_NAME
0x0020
アダプターのフレンドリ名を返しません。
GAA_FLAG_INCLUDE_WINS_INFO
0x0040
Windows Internet Name Service (WINS) サーバーのアドレスを返します。

このフラグは Windows Vista 以降でサポートされています。

GAA_FLAG_INCLUDE_GATEWAYS
0x0080
デフォルトゲートウェイのアドレスを返します。

このフラグは Windows Vista 以降でサポートされています。

GAA_FLAG_INCLUDE_ALL_INTERFACES
0x0100
すべての NDIS インターフェイスのアドレスを返します。

このフラグは Windows Vista 以降でサポートされています。

GAA_FLAG_INCLUDE_ALL_COMPARTMENTS
0x0200
すべてのルーティングコンパートメント内のアドレスを返します。

このフラグは現在サポートされておらず、将来の使用のために予約されています。

GAA_FLAG_INCLUDE_TUNNEL_BINDINGORDER
0x0400
アダプターのアドレスをトンネルバインディング順にソートして返します。このフラグは Windows Vista 以降でサポートされています。
Reservedvoid*optionalこのパラメーターは現在使用されておらず、将来のシステム用途のために予約されています。呼び出し側アプリケーションはこのパラメーターに NULL を渡してください。
AdapterAddressesIP_ADAPTER_ADDRESSES_LH*outoptional正常に復帰した場合に IP_ADAPTER_ADDRESSES 構造体の連結リストを格納するバッファーへのポインターです。
SizePointerDWORD*inoutAdapterAddresses が指すバッファーのサイズを指定する変数へのポインターです。

戻り値の型: DWORD

公式ドキュメント

ローカルコンピューター上のアダプターに関連付けられたアドレスを取得します。

戻り値

関数が成功した場合、戻り値は ERROR_SUCCESS (NO_ERROR と同じ値として定義されています) です。

関数が失敗した場合、戻り値は次のいずれかのエラーコードです。

戻り値 説明
ERROR_ADDRESS_NOT_ASSOCIATED
ネットワークエンドポイントにまだアドレスが関連付けられていません。DHCP リース情報は利用可能でした。
ERROR_BUFFER_OVERFLOW
SizePointer パラメーターで示されるバッファーサイズがアダプター情報を保持するには小さすぎるか、または AdapterAddresses パラメーターが NULL です。返された SizePointer パラメーターは、アダプター情報を保持するために必要なバッファーサイズを指します。
ERROR_INVALID_PARAMETER
いずれかのパラメーターが無効です。このエラーは次のいずれかの条件で返されます。SizePointer パラメーターが NULL である、Address パラメーターが AF_INETAF_INET6AF_UNSPEC のいずれでもない、または要求されたパラメーターのアドレス情報が ULONG_MAX を超えている。
ERROR_NOT_ENOUGH_MEMORY
操作を完了するのに十分なメモリリソースがありません。
ERROR_NO_DATA
要求されたパラメーターに対するアドレスが見つかりませんでした。
その他
返されたエラーのメッセージ文字列を取得するには FormatMessage を使用してください。

解説(Remarks)

GetAdaptersAddresses 関数は IPv4 および IPv6 アドレスの情報を取得できます。

アドレスは、AdapterAddresses パラメーターが指すバッファー内に IP_ADAPTER_ADDRESSES 構造体の連結リストとして返されます。GetAdaptersAddresses 関数を呼び出すアプリケーションは、AdapterAddresses パラメーターが指す IP_ADAPTER_ADDRESSES 構造体を返すために必要なメモリ量を割り当てなければなりません。返されたこれらの構造体が不要になったら、アプリケーションは割り当てたメモリを解放する必要があります。これは、サンプルコードに示すように、HeapAlloc 関数を呼び出してメモリを割り当て、後で HeapFree 関数を呼び出して割り当てたメモリを解放することで実現できます。割り当てと解放の両方で同じ系統の関数を使用する限り、他のメモリ割り当て・解放関数を使用することもできます。

GetAdaptersAddresses は同期関数呼び出しとしてのみ実装されています。GetAdaptersAddresses 関数は、すべての低レベルなネットワークインターフェイステーブルを走査する必要があるため、完了までに多くのネットワークリソースと時間を要します。

AdapterAddresses パラメーターが指す IP_ADAPTER_ADDRESSES 構造体を返すために必要なメモリ量を判断する方法の一つは、GetAdaptersAddresses 関数の最初の呼び出しで SizePointer パラメーターに小さすぎるバッファーサイズを渡して、関数を ERROR_BUFFER_OVERFLOW で失敗させることです。戻り値が ERROR_BUFFER_OVERFLOW の場合、返された SizePointer パラメーターは、アダプター情報を保持するために必要なバッファーサイズを指します。なお、アダプターアドレスが追加または削除された場合、GetAdaptersAddresses 関数を続けて呼び出す間に AdapterAddresses パラメーターが指す IP_ADAPTER_ADDRESSES 構造体に必要なバッファーサイズが変化する可能性があることに注意してください。ただし、この方法での GetAdaptersAddresses 関数の使用は強く推奨されません。この方法では GetAdaptersAddresses 関数を複数回呼び出す必要があります。

GetAdaptersAddresses 関数の推奨される呼び出し方法は、AdapterAddresses パラメーターが指す 15KB の作業用バッファーをあらかじめ割り当てることです。一般的なコンピューターでは、これにより GetAdaptersAddresses 関数が ERROR_BUFFER_OVERFLOW を返す可能性が大幅に減り、GetAdaptersAddresses 関数を複数回呼び出す必要がなくなります。サンプルコードはこの使用方法を示しています。

Windows 10 より前のバージョンでは、この関数が返すリスト内にアダプターが現れる順序は、[ネットワーク接続] フォルダーから制御できます。[詳細設定] メニューの [詳細設定] メニュー項目を選択します。Windows 10 以降では、リスト内にアダプターが現れる順序は IPv4 または IPv6 のルートメトリックによって決まります。

GAA_FLAG_INCLUDE_ALL_INTERFACES が設定されている場合、Family パラメーターで指定したアドレスファミリにバインドされていないアダプターに関連付けられたアドレスも含めて、すべての NDIS アダプターが取得されます。このフラグが設定されていない場合は、Family パラメーターで指定したアドレスファミリに対して有効化されたアダプターにバインドされているアドレスのみが返されます。

IP_ADAPTER_ADDRESSES 構造体のサイズは Windows XP with Service Pack 1 (SP1) 以降で変更されました。この構造体にはいくつかのメンバーが追加されました。IP_ADAPTER_ADDRESSES 構造体のサイズは Windows Vista 以降でも変更されました。この構造体には多数のメンバーが追加されました。IP_ADAPTER_ADDRESSES 構造体のサイズは、Windows Vista with Service Pack 1 (SP1) 以降および Windows Server 2008 以降でも変更されました。この構造体には 1 つのメンバーが追加されました。使用している IP_ADAPTER_ADDRESSES 構造体のバージョンを判断するには、AdapterAddresses パラメーターが指すバッファー内の構造体の連結リストで返される IP_ADAPTER_ADDRESSES 構造体の Length メンバーを使用してください。

GetIpAddrTable 関数は、ローカルコンピューター上のインターフェイスと IPv4 アドレスの対応テーブルを取得し、その情報を MIB_IPADDRTABLE 構造体で返します。

Windows Server 2003 以前向けにリリースされた Platform Software Development Kit (SDK) では、GetAdaptersAddresses 関数の戻り値は ULONG ではなく DWORD として定義されていました。

SOCKET_ADDRESS 構造体は、AdapterAddresses パラメーターが指す IP_ADAPTER_ADDRESSES 構造体内で使用されます。Windows Vista 以降向けにリリースされた Microsoft Windows Software Development Kit (SDK) では、ヘッダーファイルの構成が変更され、SOCKET_ADDRESS 構造体は Ws2def.h ヘッダーファイルで定義されています。これは Winsock2.h ヘッダーファイルによって自動的にインクルードされます。Windows Server 2003 および Windows XP 向けにリリースされた Platform SDK では、SOCKET_ADDRESS 構造体は Winsock2.h ヘッダーファイルで宣言されています。IP_ADAPTER_ADDRESSES 構造体を使用するには、Iphlpapi.h ヘッダーファイルより前に Winsock2.h ヘッダーファイルをインクルードする必要があります。

この例は、システムに関連付けられたアダプターの IP_ADAPTER_ADDRESSES 構造体を取得し、各アダプターインターフェイスについていくつかのメンバーを出力します。

#include <winsock2.h>
#include <iphlpapi.h>
#include <stdio.h>
#include <stdlib.h>

// Link with Iphlpapi.lib
#pragma comment(lib, "IPHLPAPI.lib")

#define WORKING_BUFFER_SIZE 15000
#define MAX_TRIES 3

#define MALLOC(x) HeapAlloc(GetProcessHeap(), 0, (x))
#define FREE(x) HeapFree(GetProcessHeap(), 0, (x))

/* Note: could also use malloc() and free() */

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

    /* Declare and initialize variables */

    DWORD dwRetVal = 0;

    unsigned int i = 0;

    // Set the flags to pass to GetAdaptersAddresses
    ULONG flags = GAA_FLAG_INCLUDE_PREFIX;

    // default to unspecified address family (both)
    ULONG family = AF_UNSPEC;

    LPVOID lpMsgBuf = NULL;

    PIP_ADAPTER_ADDRESSES pAddresses = NULL;
    ULONG outBufLen = 0;
    ULONG Iterations = 0;

    PIP_ADAPTER_ADDRESSES pCurrAddresses = NULL;
    PIP_ADAPTER_UNICAST_ADDRESS pUnicast = NULL;
    PIP_ADAPTER_ANYCAST_ADDRESS pAnycast = NULL;
    PIP_ADAPTER_MULTICAST_ADDRESS pMulticast = NULL;
    IP_ADAPTER_DNS_SERVER_ADDRESS *pDnServer = NULL;
    IP_ADAPTER_PREFIX *pPrefix = NULL;

    if (argc != 2) {
        printf(" Usage: getadapteraddresses family\n");
        printf("        getadapteraddresses 4 (for IPv4)\n");
        printf("        getadapteraddresses 6 (for IPv6)\n");
        printf("        getadapteraddresses A (for both IPv4 and IPv6)\n");
        exit(1);
    }

    if (atoi(argv[1]) == 4)
        family = AF_INET;
    else if (atoi(argv[1]) == 6)
        family = AF_INET6;

    printf("Calling GetAdaptersAddresses function with family = ");
    if (family == AF_INET)
        printf("AF_INET\n");
    if (family == AF_INET6)
        printf("AF_INET6\n");
    if (family == AF_UNSPEC)
        printf("AF_UNSPEC\n\n");

    // Allocate a 15 KB buffer to start with.
    outBufLen = WORKING_BUFFER_SIZE;

    do {

        pAddresses = (IP_ADAPTER_ADDRESSES *) MALLOC(outBufLen);
        if (pAddresses == NULL) {
            printf
                ("Memory allocation failed for IP_ADAPTER_ADDRESSES struct\n");
            exit(1);
        }

        dwRetVal =
            GetAdaptersAddresses(family, flags, NULL, pAddresses, &outBufLen);

        if (dwRetVal == ERROR_BUFFER_OVERFLOW) {
            FREE(pAddresses);
            pAddresses = NULL;
        } else {
            break;
        }

        Iterations++;

    } while ((dwRetVal == ERROR_BUFFER_OVERFLOW) && (Iterations < MAX_TRIES));

    if (dwRetVal == NO_ERROR) {
        // If successful, output some information from the data we received
        pCurrAddresses = pAddresses;
        while (pCurrAddresses) {
            printf("\tLength of the IP_ADAPTER_ADDRESS struct: %ld\n",
                   pCurrAddresses->Length);
            printf("\tIfIndex (IPv4 interface): %u\n", pCurrAddresses->IfIndex);
            printf("\tAdapter name: %s\n", pCurrAddresses->AdapterName);

            pUnicast = pCurrAddresses->FirstUnicastAddress;
            if (pUnicast != NULL) {
                for (i = 0; pUnicast != NULL; i++)
                    pUnicast = pUnicast->Next;
                printf("\tNumber of Unicast Addresses: %d\n", i);
            } else
                printf("\tNo Unicast Addresses\n");

            pAnycast = pCurrAddresses->FirstAnycastAddress;
            if (pAnycast) {
                for (i = 0; pAnycast != NULL; i++)
                    pAnycast = pAnycast->Next;
                printf("\tNumber of Anycast Addresses: %d\n", i);
            } else
                printf("\tNo Anycast Addresses\n");

            pMulticast = pCurrAddresses->FirstMulticastAddress;
            if (pMulticast) {
                for (i = 0; pMulticast != NULL; i++)
                    pMulticast = pMulticast->Next;
                printf("\tNumber of Multicast Addresses: %d\n", i);
            } else
                printf("\tNo Multicast Addresses\n");

            pDnServer = pCurrAddresses->FirstDnsServerAddress;
            if (pDnServer) {
                for (i = 0; pDnServer != NULL; i++)
                    pDnServer = pDnServer->Next;
                printf("\tNumber of DNS Server Addresses: %d\n", i);
            } else
                printf("\tNo DNS Server Addresses\n");

            printf("\tDNS Suffix: %wS\n", pCurrAddresses->DnsSuffix);
            printf("\tDescription: %wS\n", pCurrAddresses->Description);
            printf("\tFriendly name: %wS\n", pCurrAddresses->FriendlyName);

            if (pCurrAddresses->PhysicalAddressLength != 0) {
                printf("\tPhysical address: ");
                for (i = 0; i < (int) pCurrAddresses->PhysicalAddressLength;
                     i++) {
                    if (i == (pCurrAddresses->PhysicalAddressLength - 1))
                        printf("%.2X\n",
                               (int) pCurrAddresses->PhysicalAddress[i]);
                    else
                        printf("%.2X-",
                               (int) pCurrAddresses->PhysicalAddress[i]);
                }
            }
            printf("\tFlags: %ld\n", pCurrAddresses->Flags);
            printf("\tMtu: %lu\n", pCurrAddresses->Mtu);
            printf("\tIfType: %ld\n", pCurrAddresses->IfType);
            printf("\tOperStatus: %ld\n", pCurrAddresses->OperStatus);
            printf("\tIpv6IfIndex (IPv6 interface): %u\n",
                   pCurrAddresses->Ipv6IfIndex);
            printf("\tZoneIndices (hex): ");
            for (i = 0; i < 16; i++)
                printf("%lx ", pCurrAddresses->ZoneIndices[i]);
            printf("\n");

            printf("\tTransmit link speed: %I64u\n", pCurrAddresses->TransmitLinkSpeed);
            printf("\tReceive link speed: %I64u\n", pCurrAddresses->ReceiveLinkSpeed);

            pPrefix = pCurrAddresses->FirstPrefix;
            if (pPrefix) {
                for (i = 0; pPrefix != NULL; i++)
                    pPrefix = pPrefix->Next;
                printf("\tNumber of IP Adapter Prefix entries: %d\n", i);
            } else
                printf("\tNumber of IP Adapter Prefix entries: 0\n");

            printf("\n");

            pCurrAddresses = pCurrAddresses->Next;
        }
    } else {
        printf("Call to GetAdaptersAddresses failed with error: %d\n",
               dwRetVal);
        if (dwRetVal == ERROR_NO_DATA)
            printf("\tNo addresses were found for the requested parameters\n");
        else {

            if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
                    FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, 
                    NULL, dwRetVal, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),   
                    // Default language
                    (LPTSTR) & lpMsgBuf, 0, NULL)) {
                printf("\tError: %s", lpMsgBuf);
                LocalFree(lpMsgBuf);
                if (pAddresses)
                    FREE(pAddresses);
                exit(1);
            }
        }
    }

    if (pAddresses) {
        FREE(pAddresses);
    }

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

各言語での呼び出し定義

// IPHLPAPI.dll
#include <windows.h>

DWORD GetAdaptersAddresses(
    DWORD Family,
    GET_ADAPTERS_ADDRESSES_FLAGS Flags,
    void* Reserved,   // optional
    IP_ADAPTER_ADDRESSES_LH* AdapterAddresses,   // optional
    DWORD* SizePointer
);
[DllImport("IPHLPAPI.dll", ExactSpelling = true)]
static extern uint GetAdaptersAddresses(
    uint Family,   // DWORD
    uint Flags,   // GET_ADAPTERS_ADDRESSES_FLAGS
    IntPtr Reserved,   // void* optional
    IntPtr AdapterAddresses,   // IP_ADAPTER_ADDRESSES_LH* optional, out
    ref uint SizePointer   // DWORD* in/out
);
<DllImport("IPHLPAPI.dll", ExactSpelling:=True)>
Public Shared Function GetAdaptersAddresses(
    Family As UInteger,   ' DWORD
    Flags As UInteger,   ' GET_ADAPTERS_ADDRESSES_FLAGS
    Reserved As IntPtr,   ' void* optional
    AdapterAddresses As IntPtr,   ' IP_ADAPTER_ADDRESSES_LH* optional, out
    ByRef SizePointer As UInteger   ' DWORD* in/out
) As UInteger
End Function
' Family : DWORD
' Flags : GET_ADAPTERS_ADDRESSES_FLAGS
' Reserved : void* optional
' AdapterAddresses : IP_ADAPTER_ADDRESSES_LH* optional, out
' SizePointer : DWORD* in/out
Declare PtrSafe Function GetAdaptersAddresses Lib "iphlpapi" ( _
    ByVal Family As Long, _
    ByVal Flags As Long, _
    ByVal Reserved As LongPtr, _
    ByVal AdapterAddresses As LongPtr, _
    ByRef SizePointer As Long) As Long
' VBA7前提(PtrSafe)。32bit Office では LongPtr→Long。Integer=16bit / Long=32bit / LongLong=64bit。
import ctypes
from ctypes import wintypes

GetAdaptersAddresses = ctypes.windll.iphlpapi.GetAdaptersAddresses
GetAdaptersAddresses.restype = wintypes.DWORD
GetAdaptersAddresses.argtypes = [
    wintypes.DWORD,  # Family : DWORD
    wintypes.DWORD,  # Flags : GET_ADAPTERS_ADDRESSES_FLAGS
    ctypes.POINTER(None),  # Reserved : void* optional
    ctypes.c_void_p,  # AdapterAddresses : IP_ADAPTER_ADDRESSES_LH* optional, out
    ctypes.POINTER(wintypes.DWORD),  # SizePointer : DWORD* in/out
]
require 'fiddle'
require 'fiddle/import'

lib = Fiddle.dlopen('IPHLPAPI.dll')
GetAdaptersAddresses = Fiddle::Function.new(
  lib['GetAdaptersAddresses'],
  [
    -Fiddle::TYPE_INT,  # Family : DWORD
    -Fiddle::TYPE_INT,  # Flags : GET_ADAPTERS_ADDRESSES_FLAGS
    Fiddle::TYPE_VOIDP,  # Reserved : void* optional
    Fiddle::TYPE_VOIDP,  # AdapterAddresses : IP_ADAPTER_ADDRESSES_LH* optional, out
    Fiddle::TYPE_VOIDP,  # SizePointer : DWORD* in/out
  ],
  -Fiddle::TYPE_INT)
#[link(name = "iphlpapi")]
extern "system" {
    fn GetAdaptersAddresses(
        Family: u32,  // DWORD
        Flags: u32,  // GET_ADAPTERS_ADDRESSES_FLAGS
        Reserved: *mut (),  // void* optional
        AdapterAddresses: *mut IP_ADAPTER_ADDRESSES_LH,  // IP_ADAPTER_ADDRESSES_LH* optional, out
        SizePointer: *mut u32  // DWORD* in/out
    ) -> u32;
}
// crates: windows-sys provides ready-made bindings for this API.
$sig = @"
[DllImport("IPHLPAPI.dll")]
public static extern uint GetAdaptersAddresses(uint Family, uint Flags, IntPtr Reserved, IntPtr AdapterAddresses, ref uint SizePointer);
"@
$api = Add-Type -MemberDefinition $sig -Name 'IPHLPAPI_GetAdaptersAddresses' -Namespace Win32 -PassThru
# $api::GetAdaptersAddresses(Family, Flags, Reserved, AdapterAddresses, SizePointer)
#uselib "IPHLPAPI.dll"
#func global GetAdaptersAddresses "GetAdaptersAddresses" sptr, sptr, sptr, sptr, sptr
; GetAdaptersAddresses Family, Flags, Reserved, varptr(AdapterAddresses), varptr(SizePointer)   ; 戻り値は stat
; Family : DWORD -> "sptr"
; Flags : GET_ADAPTERS_ADDRESSES_FLAGS -> "sptr"
; Reserved : void* optional -> "sptr"
; AdapterAddresses : IP_ADAPTER_ADDRESSES_LH* optional, out -> "sptr"
; SizePointer : DWORD* in/out -> "sptr"
; ※HSP3.7は #func のため戻り値はシステム変数 stat に格納されます。
出力引数:
#uselib "IPHLPAPI.dll"
#cfunc global GetAdaptersAddresses "GetAdaptersAddresses" int, int, sptr, var, var
; res = GetAdaptersAddresses(Family, Flags, Reserved, AdapterAddresses, SizePointer)
; Family : DWORD -> "int"
; Flags : GET_ADAPTERS_ADDRESSES_FLAGS -> "int"
; Reserved : void* optional -> "sptr"
; AdapterAddresses : IP_ADAPTER_ADDRESSES_LH* optional, out -> "var"
; SizePointer : DWORD* in/out -> "var"
; ※出力/バッファ引数は var 方式(変数を直接渡す)。varptr 方式にも切替可。
出力引数:
; DWORD GetAdaptersAddresses(DWORD Family, GET_ADAPTERS_ADDRESSES_FLAGS Flags, void* Reserved, IP_ADAPTER_ADDRESSES_LH* AdapterAddresses, DWORD* SizePointer)
#uselib "IPHLPAPI.dll"
#cfunc global GetAdaptersAddresses "GetAdaptersAddresses" int, int, intptr, var, var
; res = GetAdaptersAddresses(Family, Flags, Reserved, AdapterAddresses, SizePointer)
; Family : DWORD -> "int"
; Flags : GET_ADAPTERS_ADDRESSES_FLAGS -> "int"
; Reserved : void* optional -> "intptr"
; AdapterAddresses : IP_ADAPTER_ADDRESSES_LH* optional, out -> "var"
; SizePointer : DWORD* in/out -> "var"
; ※出力/バッファ引数は var 方式(変数を直接渡す)。varptr 方式にも切替可。
import (
	"golang.org/x/sys/windows"
	"unsafe"
)

var (
	iphlpapi = windows.NewLazySystemDLL("IPHLPAPI.dll")
	procGetAdaptersAddresses = iphlpapi.NewProc("GetAdaptersAddresses")
)

// Family (DWORD), Flags (GET_ADAPTERS_ADDRESSES_FLAGS), Reserved (void* optional), AdapterAddresses (IP_ADAPTER_ADDRESSES_LH* optional, out), SizePointer (DWORD* in/out)
r1, _, err := procGetAdaptersAddresses.Call(
	uintptr(Family),
	uintptr(Flags),
	uintptr(Reserved),
	uintptr(AdapterAddresses),
	uintptr(SizePointer),
)
_ = err  // syscall.Errno (valid when the call sets last-error)
_ = r1   // DWORD
function GetAdaptersAddresses(
  Family: DWORD;   // DWORD
  Flags: DWORD;   // GET_ADAPTERS_ADDRESSES_FLAGS
  Reserved: Pointer;   // void* optional
  AdapterAddresses: Pointer;   // IP_ADAPTER_ADDRESSES_LH* optional, out
  SizePointer: Pointer   // DWORD* in/out
): DWORD; stdcall;
  external 'IPHLPAPI.dll' name 'GetAdaptersAddresses';
result := DllCall("IPHLPAPI\GetAdaptersAddresses"
    , "UInt", Family   ; DWORD
    , "UInt", Flags   ; GET_ADAPTERS_ADDRESSES_FLAGS
    , "Ptr", Reserved   ; void* optional
    , "Ptr", AdapterAddresses   ; IP_ADAPTER_ADDRESSES_LH* optional, out
    , "Ptr", SizePointer   ; DWORD* in/out
    , "UInt")   ; return: DWORD
●GetAdaptersAddresses(Family, Flags, Reserved, AdapterAddresses, SizePointer) = DLL("IPHLPAPI.dll", "dword GetAdaptersAddresses(dword, dword, void*, void*, void*)")
# 呼び出し: GetAdaptersAddresses(Family, Flags, Reserved, AdapterAddresses, SizePointer)
# Family : DWORD -> "dword"
# Flags : GET_ADAPTERS_ADDRESSES_FLAGS -> "dword"
# Reserved : void* optional -> "void*"
# AdapterAddresses : IP_ADAPTER_ADDRESSES_LH* optional, out -> "void*"
# SizePointer : DWORD* in/out -> "void*"
# なでしこ1は32bit・ANSI(Shift_JIS)。文字列=char*(ANSI)、ポインタ/ハンドル=void*(4byte)。
const std = @import("std");

extern "iphlpapi" fn GetAdaptersAddresses(
    Family: u32, // DWORD
    Flags: u32, // GET_ADAPTERS_ADDRESSES_FLAGS
    Reserved: ?*anyopaque, // void* optional
    AdapterAddresses: [*c]IP_ADAPTER_ADDRESSES_LH, // IP_ADAPTER_ADDRESSES_LH* optional, out
    SizePointer: [*c]u32 // DWORD* in/out
) callconv(std.os.windows.WINAPI) u32;
proc GetAdaptersAddresses(
    Family: uint32,  # DWORD
    Flags: uint32,  # GET_ADAPTERS_ADDRESSES_FLAGS
    Reserved: pointer,  # void* optional
    AdapterAddresses: ptr IP_ADAPTER_ADDRESSES_LH,  # IP_ADAPTER_ADDRESSES_LH* optional, out
    SizePointer: ptr uint32  # DWORD* in/out
): uint32 {.importc: "GetAdaptersAddresses", stdcall, dynlib: "IPHLPAPI.dll".}
pragma(lib, "iphlpapi");
extern(Windows)
uint GetAdaptersAddresses(
    uint Family,   // DWORD
    uint Flags,   // GET_ADAPTERS_ADDRESSES_FLAGS
    void* Reserved,   // void* optional
    IP_ADAPTER_ADDRESSES_LH* AdapterAddresses,   // IP_ADAPTER_ADDRESSES_LH* optional, out
    uint* SizePointer   // DWORD* in/out
);
ccall((:GetAdaptersAddresses, "IPHLPAPI.dll"), stdcall, UInt32,
      (UInt32, UInt32, Ptr{Cvoid}, Ptr{IP_ADAPTER_ADDRESSES_LH}, Ptr{UInt32}),
      Family, Flags, Reserved, AdapterAddresses, SizePointer)
# Family : DWORD -> UInt32
# Flags : GET_ADAPTERS_ADDRESSES_FLAGS -> UInt32
# Reserved : void* optional -> Ptr{Cvoid}
# AdapterAddresses : IP_ADAPTER_ADDRESSES_LH* optional, out -> Ptr{IP_ADAPTER_ADDRESSES_LH}
# SizePointer : DWORD* in/out -> Ptr{UInt32}
# stdcall は 32bit のみ意味を持つ(x64 では無視)。
local ffi = require("ffi")
ffi.cdef[[
uint32_t GetAdaptersAddresses(
    uint32_t Family,
    uint32_t Flags,
    void* Reserved,
    void* AdapterAddresses,
    uint32_t* SizePointer);
]]
local iphlpapi = ffi.load("iphlpapi")
-- iphlpapi.GetAdaptersAddresses(Family, Flags, Reserved, AdapterAddresses, SizePointer)
-- Family : DWORD
-- Flags : GET_ADAPTERS_ADDRESSES_FLAGS
-- Reserved : void* optional
-- AdapterAddresses : IP_ADAPTER_ADDRESSES_LH* optional, out
-- SizePointer : DWORD* in/out
-- 構造体/GUIDへのポインタは cdef が通るよう void* で表記(実型は各引数コメント参照)。値渡し構造体・enum は対応する typedef を cdef に追加すること。
const koffi = require('koffi');
const lib = koffi.load('IPHLPAPI.dll');
const GetAdaptersAddresses = lib.func('__stdcall', 'GetAdaptersAddresses', 'uint32_t', ['uint32_t', 'uint32_t', 'void *', 'void *', 'uint32_t *']);
// GetAdaptersAddresses(Family, Flags, Reserved, AdapterAddresses, SizePointer)
// Family : DWORD -> 'uint32_t'
// Flags : GET_ADAPTERS_ADDRESSES_FLAGS -> 'uint32_t'
// Reserved : void* optional -> 'void *'
// AdapterAddresses : IP_ADAPTER_ADDRESSES_LH* optional, out -> 'void *'
// SizePointer : DWORD* in/out -> 'uint32_t *'
// 出力ポインタは koffi.out(...) で包む。構造体は koffi.struct で定義。
const lib = Deno.dlopen("IPHLPAPI.dll", {
  GetAdaptersAddresses: { parameters: ["u32", "u32", "pointer", "pointer", "pointer"], result: "u32" },
});
// lib.symbols.GetAdaptersAddresses(Family, Flags, Reserved, AdapterAddresses, SizePointer)
// Family : DWORD -> "u32"
// Flags : GET_ADAPTERS_ADDRESSES_FLAGS -> "u32"
// Reserved : void* optional -> "pointer"
// AdapterAddresses : IP_ADAPTER_ADDRESSES_LH* optional, out -> "pointer"
// SizePointer : DWORD* in/out -> "pointer"
// 文字列引数は "buffer"(NUL 終端のバイト列を Uint8Array で渡す)。
// 値渡し構造体は { struct: [ ...field types... ] } を使用。
<?php
$ffi = FFI::cdef(<<<C
uint32_t GetAdaptersAddresses(
    uint32_t Family,
    uint32_t Flags,
    void* Reserved,
    void* AdapterAddresses,
    uint32_t* SizePointer);
C, "IPHLPAPI.dll");
// $ffi->GetAdaptersAddresses(Family, Flags, Reserved, AdapterAddresses, SizePointer);
// Family : DWORD
// Flags : GET_ADAPTERS_ADDRESSES_FLAGS
// Reserved : void* optional
// AdapterAddresses : IP_ADAPTER_ADDRESSES_LH* optional, out
// SizePointer : DWORD* in/out
// 構造体/GUIDへのポインタは cdef が通るよう void* で表記(実型は各引数コメント参照)。値渡し構造体・enum は対応する typedef を cdef に追加すること。
// WINAPI(stdcall): x64 では呼出規約が統一されるため問題なし。x86 では __stdcall 対応のラッパが必要な場合あり。
import com.sun.jna.*;
import com.sun.jna.ptr.*;
import com.sun.jna.win32.StdCallLibrary;
import com.sun.jna.win32.W32APIOptions;

public interface Iphlpapi extends StdCallLibrary {
    Iphlpapi INSTANCE = Native.load("iphlpapi", Iphlpapi.class);
    int GetAdaptersAddresses(
        int Family,   // DWORD
        int Flags,   // GET_ADAPTERS_ADDRESSES_FLAGS
        Pointer Reserved,   // void* optional
        Pointer AdapterAddresses,   // IP_ADAPTER_ADDRESSES_LH* optional, out
        IntByReference SizePointer   // DWORD* in/out
    );
}
@[Link("iphlpapi")]
lib LibIPHLPAPI
  fun GetAdaptersAddresses = GetAdaptersAddresses(
    Family : UInt32,   # DWORD
    Flags : UInt32,   # GET_ADAPTERS_ADDRESSES_FLAGS
    Reserved : Void*,   # void* optional
    AdapterAddresses : IP_ADAPTER_ADDRESSES_LH*,   # IP_ADAPTER_ADDRESSES_LH* optional, out
    SizePointer : UInt32*   # DWORD* in/out
  ) : UInt32
end
# 構造体/GUID/enum は lib 内に対応する型定義が必要。
# 呼出規約: x64 は規約統一のため OK。x86(32bit)は WINAPI=stdcall だが Crystal の fun に stdcall 付与構文がなく非対応。
import 'dart:ffi';
import 'package:ffi/ffi.dart';

typedef GetAdaptersAddressesNative = Uint32 Function(Uint32, Uint32, Pointer<Void>, Pointer<Void>, Pointer<Uint32>);
typedef GetAdaptersAddressesDart = int Function(int, int, Pointer<Void>, Pointer<Void>, Pointer<Uint32>);
final GetAdaptersAddresses = DynamicLibrary.open('IPHLPAPI.dll')
    .lookupFunction<GetAdaptersAddressesNative, GetAdaptersAddressesDart>('GetAdaptersAddresses');
// Family : DWORD -> Uint32
// Flags : GET_ADAPTERS_ADDRESSES_FLAGS -> Uint32
// Reserved : void* optional -> Pointer<Void>
// AdapterAddresses : IP_ADAPTER_ADDRESSES_LH* optional, out -> Pointer<Void>
// SizePointer : DWORD* in/out -> Pointer<Uint32>
// 文字列は package:ffi の "...".toNativeUtf16()/toNativeUtf8() で変換。
{$mode objfpc}{$H+}
function GetAdaptersAddresses(
  Family: DWORD;   // DWORD
  Flags: DWORD;   // GET_ADAPTERS_ADDRESSES_FLAGS
  Reserved: Pointer;   // void* optional
  AdapterAddresses: Pointer;   // IP_ADAPTER_ADDRESSES_LH* optional, out
  SizePointer: Pointer   // DWORD* in/out
): DWORD; stdcall;
  external 'IPHLPAPI.dll' name 'GetAdaptersAddresses';
import Foreign
import Foreign.C.Types
import Foreign.C.String

foreign import stdcall safe "GetAdaptersAddresses"
  c_GetAdaptersAddresses :: Word32 -> Word32 -> Ptr () -> Ptr () -> Ptr Word32 -> IO Word32
-- Family : DWORD -> Word32
-- Flags : GET_ADAPTERS_ADDRESSES_FLAGS -> Word32
-- Reserved : void* optional -> Ptr ()
-- AdapterAddresses : IP_ADAPTER_ADDRESSES_LH* optional, out -> Ptr ()
-- SizePointer : DWORD* in/out -> Ptr Word32
-- 要 GHC(Windows)。stdcall は x64 では ccall として扱われる。ブロックする API は safe 呼び出し推奨。
open Ctypes
open Foreign

let getadaptersaddresses =
  foreign "GetAdaptersAddresses"
    (uint32_t @-> uint32_t @-> (ptr void) @-> (ptr void) @-> (ptr uint32_t) @-> returning uint32_t)
(* Family : DWORD -> uint32_t *)
(* Flags : GET_ADAPTERS_ADDRESSES_FLAGS -> uint32_t *)
(* Reserved : void* optional -> (ptr void) *)
(* AdapterAddresses : IP_ADAPTER_ADDRESSES_LH* optional, out -> (ptr void) *)
(* SizePointer : DWORD* in/out -> (ptr uint32_t) *)
(* foreign は cdecl 前提。x64 Windows では WINAPI と一致。構造体は ctypes structure を定義のこと。 *)
(cffi:define-foreign-library iphlpapi (t "IPHLPAPI.dll"))
(cffi:use-foreign-library iphlpapi)

(cffi:defcfun ("GetAdaptersAddresses" get-adapters-addresses :convention :stdcall) :uint32
  (family :uint32)   ; DWORD
  (flags :uint32)   ; GET_ADAPTERS_ADDRESSES_FLAGS
  (reserved :pointer)   ; void* optional
  (adapter-addresses :pointer)   ; IP_ADAPTER_ADDRESSES_LH* optional, out
  (size-pointer :pointer))   ; DWORD* in/out
; isize/usize(INT_PTR/SIZE_T)は x64 前提で :int64/:uint64。x86 では :int32/:uint32。
use Win32::API;
my $GetAdaptersAddresses = Win32::API::More->new('IPHLPAPI',
    'DWORD GetAdaptersAddresses(DWORD Family, DWORD Flags, LPVOID Reserved, LPVOID AdapterAddresses, LPVOID SizePointer)');
# my $ret = $GetAdaptersAddresses->Call($Family, $Flags, $Reserved, $AdapterAddresses, $SizePointer);
# Family : DWORD -> DWORD
# Flags : GET_ADAPTERS_ADDRESSES_FLAGS -> DWORD
# Reserved : void* optional -> LPVOID
# AdapterAddresses : IP_ADAPTER_ADDRESSES_LH* optional, out -> LPVOID
# SizePointer : DWORD* in/out -> LPVOID
# 値渡し構造体は pack() した文字列、または Win32::API::Struct を使用。

関連項目

公式の関連項目
使用する型