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

AddIPAddress

関数
指定インターフェイスに新しいIPv4アドレスを追加する。
DLLIPHLPAPI.dll呼出規約winapi対応OSWindows 2000 以降

シグネチャ

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

DWORD AddIPAddress(
    DWORD Address,
    DWORD IpMask,
    DWORD IfIndex,
    DWORD* NTEContext,
    DWORD* NTEInstance
);

パラメーター

名前方向説明
AddressDWORDinアダプターに追加する IPv4 アドレス。IPAddr 構造体の形式で指定します。
IpMaskDWORDinAddress パラメーターで指定した IPv4 アドレスのサブネットマスク。IPMask パラメーターは IPAddr 構造体と同じ形式を使用します。
IfIndexDWORDinIPv4 アドレスを追加する対象アダプターのインデックス。
NTEContextDWORD*outULONG 変数へのポインター。正常に復帰した場合、このパラメーターは追加された IPv4 アドレスの Net Table Entry (NTE) コンテキストを指します。呼び出し元は後で、このコンテキストを DeleteIPAddress 関数の呼び出しに使用できます。
NTEInstanceDWORD*outULONG 変数へのポインター。正常に復帰した場合、このパラメーターは追加された IPv4 アドレスの NTE インスタンスを指します。

戻り値の型: DWORD

公式ドキュメント

AddIPAddress 関数は、指定した IPv4 アドレスを指定したアダプターに追加します。

戻り値

関数が成功した場合、戻り値は NO_ERROR です。

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

戻り値 説明
ERROR_DEV_NOT_EXIST
IfIndex パラメーターで指定されたアダプターが存在しません。
ERROR_DUP_DOMAINNAME
Address パラメーターで指定された、追加しようとする IPv4 アドレスが既に存在します。
ERROR_GEN_FAILURE
一般的な障害です。このエラーは、Address パラメーターに指定された一部の値(通常はブロードキャストアドレスと見なされる IPv4 アドレスなど)に対して返されます。
ERROR_INVALID_HANDLE
関数を呼び出そうとしているユーザーが管理者ではありません。
ERROR_INVALID_PARAMETER
1 つ以上のパラメーターが無効です。このエラーは、NTEContext または NTEInstance パラメーターが NULL の場合に返されます。また、Address パラメーターで指定された IP アドレスが IfIndex パラメーターで指定されたインターフェイスインデックスと整合しない場合(たとえば、非ループバックインターフェイス上のループバックアドレスなど)にも返されます。
ERROR_NOT_SUPPORTED
この関数呼び出しは、実行された Windows のバージョンではサポートされていません。
その他
返されたエラーのメッセージ文字列を取得するには、 FormatMessage を使用してください。

解説(Remarks)

AddIPAddress 関数は、ローカルコンピューター上に新しい IPv4 アドレスエントリを追加するために使用します。AddIPAddress 関数によって追加された IPv4 アドレスは永続的ではありません。この IPv4 アドレスはアダプターオブジェクトが存在する間のみ存在します。コンピューターを再起動すると IPv4 アドレスは破棄され、ネットワークインターフェイスカード (NIC) を手動でリセットした場合も同様です。また、特定の PnP イベントによってアドレスが破棄されることがあります。

永続的な IPv4 アドレスを作成するには、Windows Management Instrumentation (WMI) コントロールの Win32_NetworkAdapterConfiguration クラスの EnableStatic メソッド を使用できます。netsh コマンドを使用して永続的な IPv4 アドレスを作成することもできます。

詳細については、Windows Sockets のドキュメント内の Netsh.exe に関するドキュメントを参照してください。

Windows Server 2003、Windows XP、Windows 2000 では、Address パラメーターの IPv4 アドレスがネットワーク上に既に存在する場合、AddIPAddress 関数は NO_ERROR を返し、追加される IPv4 アドレスは 0.0.0.0 になります。

Windows Vista 以降では、Address パラメーターで渡された IPv4 アドレスがネットワーク上に既に存在する場合、AddIPAddress 関数は NO_ERROR を返し、重複した IPv4 アドレスは IP_ADAPTER_UNICAST_ADDRESS 構造体の IP_DAD_STATE メンバーが IpDadStateDuplicate に設定された状態で追加されます。

AddIPAddress 関数を使用して追加した IPv4 アドレスは、後で DeleteIPAddress 関数を呼び出し、AddIPAddress 関数が返した NTEContext パラメーターを渡すことで削除できます。

IPAddr および IPMask データ型については、 Windows Data Types を参照してください。IPv4 アドレスをドット付き 10 進表記と IPAddr 形式の間で変換するには、 inet_addr および inet_ntoa 関数を使用してください。

Windows Vista 以降では、CreateUnicastIpAddressEntry 関数を使用して、ローカルコンピューター上に新しいユニキャスト IPv4 または IPv6 アドレスエントリを追加できます。

次の例では、IP アドレステーブルを取得して最初のアダプターのインターフェイスインデックスを判別し、コマンドラインで指定された IP アドレスを最初のアダプターに追加します。追加した IP アドレスはその後削除されます。

#pragma comment(lib, "iphlpapi.lib")
#pragma comment(lib, "ws2_32.lib")

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

#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)
{

    /* Variables used by GetIpAddrTable */
    PMIB_IPADDRTABLE pIPAddrTable;
    DWORD dwSize = 0;
    DWORD dwRetVal = 0;
    IN_ADDR IPAddr;
    DWORD ifIndex;

    /* IPv4 address and subnet mask we will be adding */
    UINT iaIPAddress;
    UINT iaIPMask;

    /* Variables where handles to the added IP are returned */
    ULONG NTEContext = 0;
    ULONG NTEInstance = 0;

    /* Variables used to return error message */
    LPVOID lpMsgBuf;

    // Validate the parameters
    if (argc != 3) {
        printf("usage: %s IPAddress SubnetMask\n", argv[0]);
        exit(1);
    }

    iaIPAddress = inet_addr(argv[1]);
    if (iaIPAddress == INADDR_NONE) {
        printf("usage: %s IPAddress SubnetMask\n", argv[0]);
        exit(1);
    }

    iaIPMask = inet_addr(argv[2]);
    if (iaIPMask == INADDR_NONE) {
        printf("usage: %s IPAddress SubnetMask\n", argv[0]);
        exit(1);
    }

    // Before calling AddIPAddress we use GetIpAddrTable to get
    // an adapter to which we can add the IP.
    pIPAddrTable = (MIB_IPADDRTABLE *) MALLOC(sizeof (MIB_IPADDRTABLE));
    if (pIPAddrTable == NULL) {
        printf("Error allocating memory needed to call GetIpAddrTable\n");
        exit (1);
    }
    else {
        dwSize = 0;
        // Make an initial call to GetIpAddrTable to get the
        // necessary size into the dwSize variable
        if (GetIpAddrTable(pIPAddrTable, &dwSize, 0) ==
            ERROR_INSUFFICIENT_BUFFER) {
            FREE(pIPAddrTable);
            pIPAddrTable = (MIB_IPADDRTABLE *) MALLOC(dwSize);

        }
        if (pIPAddrTable == NULL) {
            printf("Memory allocation failed for GetIpAddrTable\n");
            exit(1);
        }
    }
    // Make a second call to GetIpAddrTable to get the
    // actual data we want
    if ((dwRetVal = GetIpAddrTable(pIPAddrTable, &dwSize, 0)) == NO_ERROR) {
        // Save the interface index to use for adding an IP address
        ifIndex = pIPAddrTable->table[0].dwIndex;
        printf("\n\tInterface Index:\t%ld\n", ifIndex);
        IPAddr.S_un.S_addr = (u_long) pIPAddrTable->table[0].dwAddr;
        printf("\tIP Address:       \t%s (%lu%)\n", inet_ntoa(IPAddr),
               pIPAddrTable->table[0].dwAddr);
        IPAddr.S_un.S_addr = (u_long) pIPAddrTable->table[0].dwMask;
        printf("\tSubnet Mask:      \t%s (%lu%)\n", inet_ntoa(IPAddr),
               pIPAddrTable->table[0].dwMask);
        IPAddr.S_un.S_addr = (u_long) pIPAddrTable->table[0].dwBCastAddr;
        printf("\tBroadCast Address:\t%s (%lu%)\n", inet_ntoa(IPAddr),
               pIPAddrTable->table[0].dwBCastAddr);
        printf("\tReassembly size:  \t%lu\n\n",
               pIPAddrTable->table[0].dwReasmSize);
    } else {
        printf("Call to GetIpAddrTable failed with error %d.\n", dwRetVal);
        if (pIPAddrTable)
            FREE(pIPAddrTable);
        exit(1);
    }

    if (pIPAddrTable) {
        FREE(pIPAddrTable);
        pIPAddrTable = NULL;
    }

    if ((dwRetVal = AddIPAddress(iaIPAddress,
                                 iaIPMask,
                                 ifIndex,
                                 &NTEContext, &NTEInstance)) == NO_ERROR) {
        printf("\tIPv4 address %s was successfully added.\n", argv[1]);
    } else {
        printf("AddIPAddress failed with error: %d\n", dwRetVal);

        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);
            exit(1);
        }
    }

// Delete the IP we just added using the NTEContext
// variable where the handle was returned       
    if ((dwRetVal = DeleteIPAddress(NTEContext)) == NO_ERROR) {
        printf("\tIPv4 address %s was successfully deleted.\n", argv[1]);
    } else {
        printf("\tDeleteIPAddress failed with error: %d\n", dwRetVal);
        exit(1);
    }

    exit(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 AddIPAddress(
    DWORD Address,
    DWORD IpMask,
    DWORD IfIndex,
    DWORD* NTEContext,
    DWORD* NTEInstance
);
[DllImport("IPHLPAPI.dll", ExactSpelling = true)]
static extern uint AddIPAddress(
    uint Address,   // DWORD
    uint IpMask,   // DWORD
    uint IfIndex,   // DWORD
    out uint NTEContext,   // DWORD* out
    out uint NTEInstance   // DWORD* out
);
<DllImport("IPHLPAPI.dll", ExactSpelling:=True)>
Public Shared Function AddIPAddress(
    Address As UInteger,   ' DWORD
    IpMask As UInteger,   ' DWORD
    IfIndex As UInteger,   ' DWORD
    <Out> ByRef NTEContext As UInteger,   ' DWORD* out
    <Out> ByRef NTEInstance As UInteger   ' DWORD* out
) As UInteger
End Function
' Address : DWORD
' IpMask : DWORD
' IfIndex : DWORD
' NTEContext : DWORD* out
' NTEInstance : DWORD* out
Declare PtrSafe Function AddIPAddress Lib "iphlpapi" ( _
    ByVal Address As Long, _
    ByVal IpMask As Long, _
    ByVal IfIndex As Long, _
    ByRef NTEContext As Long, _
    ByRef NTEInstance As Long) As Long
' VBA7前提(PtrSafe)。32bit Office では LongPtr→Long。Integer=16bit / Long=32bit / LongLong=64bit。
import ctypes
from ctypes import wintypes

AddIPAddress = ctypes.windll.iphlpapi.AddIPAddress
AddIPAddress.restype = wintypes.DWORD
AddIPAddress.argtypes = [
    wintypes.DWORD,  # Address : DWORD
    wintypes.DWORD,  # IpMask : DWORD
    wintypes.DWORD,  # IfIndex : DWORD
    ctypes.POINTER(wintypes.DWORD),  # NTEContext : DWORD* out
    ctypes.POINTER(wintypes.DWORD),  # NTEInstance : DWORD* out
]
require 'fiddle'
require 'fiddle/import'

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

var (
	iphlpapi = windows.NewLazySystemDLL("IPHLPAPI.dll")
	procAddIPAddress = iphlpapi.NewProc("AddIPAddress")
)

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

extern "iphlpapi" fn AddIPAddress(
    Address: u32, // DWORD
    IpMask: u32, // DWORD
    IfIndex: u32, // DWORD
    NTEContext: [*c]u32, // DWORD* out
    NTEInstance: [*c]u32 // DWORD* out
) callconv(std.os.windows.WINAPI) u32;
proc AddIPAddress(
    Address: uint32,  # DWORD
    IpMask: uint32,  # DWORD
    IfIndex: uint32,  # DWORD
    NTEContext: ptr uint32,  # DWORD* out
    NTEInstance: ptr uint32  # DWORD* out
): uint32 {.importc: "AddIPAddress", stdcall, dynlib: "IPHLPAPI.dll".}
pragma(lib, "iphlpapi");
extern(Windows)
uint AddIPAddress(
    uint Address,   // DWORD
    uint IpMask,   // DWORD
    uint IfIndex,   // DWORD
    uint* NTEContext,   // DWORD* out
    uint* NTEInstance   // DWORD* out
);
ccall((:AddIPAddress, "IPHLPAPI.dll"), stdcall, UInt32,
      (UInt32, UInt32, UInt32, Ptr{UInt32}, Ptr{UInt32}),
      Address, IpMask, IfIndex, NTEContext, NTEInstance)
# Address : DWORD -> UInt32
# IpMask : DWORD -> UInt32
# IfIndex : DWORD -> UInt32
# NTEContext : DWORD* out -> Ptr{UInt32}
# NTEInstance : DWORD* out -> Ptr{UInt32}
# stdcall は 32bit のみ意味を持つ(x64 では無視)。
local ffi = require("ffi")
ffi.cdef[[
uint32_t AddIPAddress(
    uint32_t Address,
    uint32_t IpMask,
    uint32_t IfIndex,
    uint32_t* NTEContext,
    uint32_t* NTEInstance);
]]
local iphlpapi = ffi.load("iphlpapi")
-- iphlpapi.AddIPAddress(Address, IpMask, IfIndex, NTEContext, NTEInstance)
-- Address : DWORD
-- IpMask : DWORD
-- IfIndex : DWORD
-- NTEContext : DWORD* out
-- NTEInstance : DWORD* out
-- 構造体/GUIDへのポインタは cdef が通るよう void* で表記(実型は各引数コメント参照)。値渡し構造体・enum は対応する typedef を cdef に追加すること。
const koffi = require('koffi');
const lib = koffi.load('IPHLPAPI.dll');
const AddIPAddress = lib.func('__stdcall', 'AddIPAddress', 'uint32_t', ['uint32_t', 'uint32_t', 'uint32_t', 'uint32_t *', 'uint32_t *']);
// AddIPAddress(Address, IpMask, IfIndex, NTEContext, NTEInstance)
// Address : DWORD -> 'uint32_t'
// IpMask : DWORD -> 'uint32_t'
// IfIndex : DWORD -> 'uint32_t'
// NTEContext : DWORD* out -> 'uint32_t *'
// NTEInstance : DWORD* out -> 'uint32_t *'
// 出力ポインタは koffi.out(...) で包む。構造体は koffi.struct で定義。
const lib = Deno.dlopen("IPHLPAPI.dll", {
  AddIPAddress: { parameters: ["u32", "u32", "u32", "pointer", "pointer"], result: "u32" },
});
// lib.symbols.AddIPAddress(Address, IpMask, IfIndex, NTEContext, NTEInstance)
// Address : DWORD -> "u32"
// IpMask : DWORD -> "u32"
// IfIndex : DWORD -> "u32"
// NTEContext : DWORD* out -> "pointer"
// NTEInstance : DWORD* out -> "pointer"
// 文字列引数は "buffer"(NUL 終端のバイト列を Uint8Array で渡す)。
// 値渡し構造体は { struct: [ ...field types... ] } を使用。
<?php
$ffi = FFI::cdef(<<<C
uint32_t AddIPAddress(
    uint32_t Address,
    uint32_t IpMask,
    uint32_t IfIndex,
    uint32_t* NTEContext,
    uint32_t* NTEInstance);
C, "IPHLPAPI.dll");
// $ffi->AddIPAddress(Address, IpMask, IfIndex, NTEContext, NTEInstance);
// Address : DWORD
// IpMask : DWORD
// IfIndex : DWORD
// NTEContext : DWORD* out
// NTEInstance : DWORD* 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 AddIPAddress(
        int Address,   // DWORD
        int IpMask,   // DWORD
        int IfIndex,   // DWORD
        IntByReference NTEContext,   // DWORD* out
        IntByReference NTEInstance   // DWORD* out
    );
}
@[Link("iphlpapi")]
lib LibIPHLPAPI
  fun AddIPAddress = AddIPAddress(
    Address : UInt32,   # DWORD
    IpMask : UInt32,   # DWORD
    IfIndex : UInt32,   # DWORD
    NTEContext : UInt32*,   # DWORD* out
    NTEInstance : UInt32*   # DWORD* out
  ) : UInt32
end
# 構造体/GUID/enum は lib 内に対応する型定義が必要。
# 呼出規約: x64 は規約統一のため OK。x86(32bit)は WINAPI=stdcall だが Crystal の fun に stdcall 付与構文がなく非対応。
import 'dart:ffi';
import 'package:ffi/ffi.dart';

typedef AddIPAddressNative = Uint32 Function(Uint32, Uint32, Uint32, Pointer<Uint32>, Pointer<Uint32>);
typedef AddIPAddressDart = int Function(int, int, int, Pointer<Uint32>, Pointer<Uint32>);
final AddIPAddress = DynamicLibrary.open('IPHLPAPI.dll')
    .lookupFunction<AddIPAddressNative, AddIPAddressDart>('AddIPAddress');
// Address : DWORD -> Uint32
// IpMask : DWORD -> Uint32
// IfIndex : DWORD -> Uint32
// NTEContext : DWORD* out -> Pointer<Uint32>
// NTEInstance : DWORD* out -> Pointer<Uint32>
// 文字列は package:ffi の "...".toNativeUtf16()/toNativeUtf8() で変換。
{$mode objfpc}{$H+}
function AddIPAddress(
  Address: DWORD;   // DWORD
  IpMask: DWORD;   // DWORD
  IfIndex: DWORD;   // DWORD
  NTEContext: Pointer;   // DWORD* out
  NTEInstance: Pointer   // DWORD* out
): DWORD; stdcall;
  external 'IPHLPAPI.dll' name 'AddIPAddress';
import Foreign
import Foreign.C.Types
import Foreign.C.String

foreign import stdcall safe "AddIPAddress"
  c_AddIPAddress :: Word32 -> Word32 -> Word32 -> Ptr Word32 -> Ptr Word32 -> IO Word32
-- Address : DWORD -> Word32
-- IpMask : DWORD -> Word32
-- IfIndex : DWORD -> Word32
-- NTEContext : DWORD* out -> Ptr Word32
-- NTEInstance : DWORD* out -> Ptr Word32
-- 要 GHC(Windows)。stdcall は x64 では ccall として扱われる。ブロックする API は safe 呼び出し推奨。
open Ctypes
open Foreign

let addipaddress =
  foreign "AddIPAddress"
    (uint32_t @-> uint32_t @-> uint32_t @-> (ptr uint32_t) @-> (ptr uint32_t) @-> returning uint32_t)
(* Address : DWORD -> uint32_t *)
(* IpMask : DWORD -> uint32_t *)
(* IfIndex : DWORD -> uint32_t *)
(* NTEContext : DWORD* out -> (ptr uint32_t) *)
(* NTEInstance : DWORD* 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 ("AddIPAddress" add-ipaddress :convention :stdcall) :uint32
  (address :uint32)   ; DWORD
  (ip-mask :uint32)   ; DWORD
  (if-index :uint32)   ; DWORD
  (ntecontext :pointer)   ; DWORD* out
  (nteinstance :pointer))   ; DWORD* out
; isize/usize(INT_PTR/SIZE_T)は x64 前提で :int64/:uint64。x86 では :int32/:uint32。
use Win32::API;
my $AddIPAddress = Win32::API::More->new('IPHLPAPI',
    'DWORD AddIPAddress(DWORD Address, DWORD IpMask, DWORD IfIndex, LPVOID NTEContext, LPVOID NTEInstance)');
# my $ret = $AddIPAddress->Call($Address, $IpMask, $IfIndex, $NTEContext, $NTEInstance);
# Address : DWORD -> DWORD
# IpMask : DWORD -> DWORD
# IfIndex : DWORD -> DWORD
# NTEContext : DWORD* out -> LPVOID
# NTEInstance : DWORD* out -> LPVOID
# 値渡し構造体は pack() した文字列、または Win32::API::Struct を使用。

関連項目

公式の関連項目