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

SendARP

関数
指定IPv4アドレスにARP要求を送り物理アドレスを取得する。
DLLIPHLPAPI.dll呼出規約winapi対応OSWindows 2000 以降

シグネチャ

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

DWORD SendARP(
    DWORD DestIP,
    DWORD SrcIP,
    void* pMacAddr,
    DWORD* PhyAddrLen
);

パラメーター

名前方向説明
DestIPDWORDin宛先 IPv4 アドレス。IPAddr 構造体の形式で指定します。ARP 要求は、この IPv4 アドレスに対応する物理アドレスの取得を試みます。
SrcIPDWORDin送信元の IPv4 アドレス。IPAddr 構造体の形式で指定します。このパラメーターは省略可能で、ARP エントリの要求を送信するインターフェイスを選択するために使用されます。呼び出し側は、このパラメーターに INADDR_ANY の IPv4 アドレスに相当する 0 を指定できます。
pMacAddrvoid*outULONG 変数の配列へのポインター。この配列は、Ethernet またはトークンリングの物理アドレスを格納するために、少なくとも 2 つの ULONG 要素を持つ必要があります。この配列の先頭 6 バイトに、DestIP パラメーターで指定した IPv4 アドレスに対応する物理アドレスが格納されます。
PhyAddrLenDWORD*inout

入力時には、アプリケーションが物理アドレス (MAC アドレス) を受け取るために用意したバッファーの最大サイズ (バイト単位) を指定する ULONG 値へのポインターです。バッファーサイズは、Ethernet またはトークンリングの物理アドレスの場合、少なくとも 6 バイト必要です。

物理アドレスを受け取るバッファーは、pMacAddr パラメーターで指定します。

正常に出力された場合、このパラメーターは pMacAddr が指すバッファーに書き込まれたバイト数を示す値を指します。

戻り値の型: DWORD

公式ドキュメント

SendARP 関数は、指定した宛先 IPv4 アドレスに対応する物理アドレスを取得するために、Address Resolution Protocol (ARP) 要求を送信します。

戻り値

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

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

戻り値 説明
ERROR_BAD_NET_NAME
ネットワーク名が見つかりません。このエラーは、Windows Vista 以降で、SendARP 要求に対する ARP 応答が受信されなかった場合に返されます。このエラーは、宛先 IPv4 アドレスが同じサブネット上にないため、または宛先コンピューターが稼働していないために到達できなかった場合に発生します。
ERROR_BUFFER_OVERFLOW
ファイル名が長すぎます。このエラーは、Windows Vista で、PhyAddrLen パラメーターが指す ULONG 値が、完全な物理アドレスを格納するのに必要なサイズである 6 未満の場合に返されます。
ERROR_GEN_FAILURE
システムに接続されたデバイスが機能していません。このエラーは、Windows Server 2003 以前で、SendARP 要求に対する ARP 応答が受信されなかった場合に返されます。このエラーは、宛先 IPv4 アドレスが同じサブネット上にないため、または宛先コンピューターが稼働していないために到達できなかった場合に発生することがあります。
ERROR_INVALID_PARAMETER
パラメーターのいずれかが無効です。このエラーは、Windows Server 2003 以前で、pMacAddr または PhyAddrLen パラメーターが NULL ポインターの場合に返されます。
ERROR_INVALID_USER_BUFFER
指定されたユーザーバッファーが、要求された操作に対して無効です。このエラーは、Windows Server 2003 以前で、PhyAddrLen パラメーターが指す ULONG 値が 0 の場合に返されます。
ERROR_NOT_FOUND
要素が見つかりません。このエラーは、Windows Vista で、SrcIp パラメーターがローカルコンピューター上のインターフェイスの送信元 IPv4 アドレスも INADDR_ANY IP アドレス (0.0.0.0 という IPv4 アドレス) も指定していない場合に返されます。
ERROR_NOT_SUPPORTED
SendARP 関数は、ローカルコンピューターで動作しているオペレーティングシステムでサポートされていません。
その他
関数が失敗した場合は、FormatMessage を使用して、返されたエラーのメッセージ文字列を取得してください。

解説(Remarks)

SendARP 関数は、指定した宛先 IPv4 アドレスに対応する物理ハードウェアアドレス (MAC アドレスと呼ばれることもあります) を要求するために使用します。要求された情報がローカルコンピューターの ARP テーブルにない場合、SendARP 関数は物理アドレスを取得するための ARP 要求を送信させます。関数が成功すると、指定した宛先 IPv4 アドレスに対応する物理アドレスが、pMacAddr パラメーターが指す配列に返されます。

IPv4 アドレスの物理アドレスは、宛先 IPv4 アドレスがローカルサブネット上にある場合 (ルーターを経由せずに直接 IPv4 アドレスに到達できる場合) にのみ取得できます。宛先 IPv4 アドレスがローカルサブネット上にない場合、SendARP 関数は失敗します。

Windows Vista 以降で SendARP 関数が成功すると、ローカルコンピューターの ARP テーブルがその結果で更新されます。Windows Server 2003 以前で SendARP 関数が成功した場合、ローカルコンピューターの ARP テーブルは影響を受けません。

Windows Vista 以降の SendARP 関数は、Windows Server 2003 以前の SendARP 関数とは異なるエラー戻り値を返します。

Windows Vista 以降では、pMacAddr または PhyAddrLen パラメーターに NULL ポインターを渡すと、アクセス違反が発生してアプリケーションが終了します。Windows Vista 以降でエラーが発生し、ERROR_BAD_NET_NAMEERROR_BUFFER_OVERFLOW、または ERROR_NOT_FOUND が返された場合、PhyAddrLen パラメーターが指す ULONG 値は 0 に設定されます。Windows Vista 以降で PhyAddrLen パラメーターが指す ULONG 値が 6 未満の場合、SendARP 関数は物理アドレスを受け取るバッファーが小さすぎることを示す ERROR_BUFFER_OVERFLOW を返します。SrcIp パラメーターがローカルコンピューターのインターフェイスではない IPv4 アドレスを指定している場合、Windows Vista 以降の SendARP 関数は ERROR_NOT_FOUND を返します。

Windows Server 2003 以前では、pMacAddr または PhyAddrLen パラメーターに NULL ポインターを渡すと、SendARP 関数は ERROR_INVALID_PARAMETER を返します。Windows Server 2003 以前でエラーが発生し、ERROR_GEN_FAILURE または ERROR_INVALID_USER_BUFFER が返された場合、PhyAddrLen パラメーターが指す ULONG 値は 0 に設定されます。Windows Server 2003 以前で PhyAddrLen パラメーターが指す ULONG 値が 6 未満の場合、SendARP 関数はエラーを返さず、pMacAddr パラメーターが指す配列にハードウェアアドレスの一部のみを返します。したがって、PhyAddrLen パラメーターが指す値が 4 の場合、ハードウェアアドレスの先頭 4 バイトのみが pMacAddr パラメーターが指す配列に返されます。SrcIp パラメーターがローカルコンピューターのインターフェイスではない IPv4 アドレスを指定している場合、Windows Server 2003 以前の SendARP 関数は SrcIp パラメーターを無視し、送信元 IPv4 アドレスとしてローカルコンピューターの IPv4 アドレスを使用します。

GetIpNetTable 関数は、IPv4 アドレスを物理アドレスにマッピングするローカルコンピューターの ARP テーブルを取得します。

CreateIpNetEntry 関数は、ローカルコンピューターの ARP テーブルに ARP エントリを作成します。

DeleteIpNetEntry 関数は、ローカルコンピューターの ARP テーブルから ARP エントリを削除します。

SetIpNetEntry 関数は、ローカルコンピューターの ARP テーブル内の既存の ARP エントリを変更します。

FlushIpNetTable 関数は、指定したインターフェイスのすべての ARP エントリを、ローカルコンピューターの ARP テーブルから削除します。

Windows Vista 以降では、ResolveIpNetEntry2 関数を使用して SendARP 関数を置き換えることができます。ResolveIpNetEntry2 関数に渡される MIB_IPNET_ROW2 構造体の Address メンバーが IPv4 アドレスの場合、ARP 要求が送信されます。

Windows Vista では、これらの関数に渡される MIB_IPNET_ROW2 構造体の Address メンバーが IPv4 アドレスの場合に、ARP テーブルのエントリへのアクセス、変更、削除を行うための新しい関数グループを使用できます。新しい関数には次のものがあります: GetIpNetTable2CreateIpNetEntry2DeleteIpNetEntry2FlushIpNetTable2、および SetIpNetEntry2

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

次のコードは、指定した IPv4 アドレスに関連付けられたハードウェアアドレスまたはメディアアクセス制御 (MAC) アドレスを取得する方法を示しています。

#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif

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

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

void usage(char *pname)
{
    printf("Usage: %s [options] ip-address\n", pname);
    printf("\t -h \t\thelp\n");
    printf("\t -l length \tMAC physical address length to set\n");
    printf("\t -s src-ip \tsource IP address\n");
    exit(1);
}

int __cdecl main(int argc, char **argv)
{
    DWORD dwRetVal;
    IPAddr DestIp = 0;
    IPAddr SrcIp = 0;       /* default for src ip */
    ULONG MacAddr[2];       /* for 6-byte hardware addresses */
    ULONG PhysAddrLen = 6;  /* default to length of six bytes */

    char *DestIpString = NULL;
    char *SrcIpString = NULL;

    BYTE *bPhysAddr;
    unsigned int i;

    if (argc > 1) {
        for (i = 1; i < (unsigned int) argc; i++) {
            if ((argv[i][0] == '-') || (argv[i][0] == '/')) {
                switch (tolower(argv[i][1])) {
                case 'l':
                    PhysAddrLen = (ULONG) atol(argv[++i]);
                    break;
                case 's':
                    SrcIpString = argv[++i];
                    SrcIp = inet_addr(SrcIpString);
                    break;
                case 'h':
                default:
                    usage(argv[0]);
                    break;
                }               /* end switch */
            } else
                DestIpString = argv[i];
        }                       /* end for */
    } else
        usage(argv[0]);

    if (DestIpString == NULL || DestIpString[0] == '\0')
        usage(argv[0]);

    DestIp = inet_addr(DestIpString);

    memset(&MacAddr, 0xff, sizeof (MacAddr));

    printf("Sending ARP request for IP address: %s\n", DestIpString);

    dwRetVal = SendARP(DestIp, SrcIp, &MacAddr, &PhysAddrLen);

    if (dwRetVal == NO_ERROR) {
        bPhysAddr = (BYTE *) & MacAddr;
        if (PhysAddrLen) {
            for (i = 0; i < (int) PhysAddrLen; i++) {
                if (i == (PhysAddrLen - 1))
                    printf("%.2X\n", (int) bPhysAddr[i]);
                else
                    printf("%.2X-", (int) bPhysAddr[i]);
            }
        } else
            printf
                ("Warning: SendArp completed successfully, but returned length=0\n");

    } else {
        printf("Error: SendArp failed with error: %d", dwRetVal);
        switch (dwRetVal) {
        case ERROR_GEN_FAILURE:
            printf(" (ERROR_GEN_FAILURE)\n");
            break;
        case ERROR_INVALID_PARAMETER:
            printf(" (ERROR_INVALID_PARAMETER)\n");
            break;
        case ERROR_INVALID_USER_BUFFER:
            printf(" (ERROR_INVALID_USER_BUFFER)\n");
            break;
        case ERROR_BAD_NET_NAME:
            printf(" (ERROR_GEN_FAILURE)\n");
            break;
        case ERROR_BUFFER_OVERFLOW:
            printf(" (ERROR_BUFFER_OVERFLOW)\n");
            break;
        case ERROR_NOT_FOUND:
            printf(" (ERROR_NOT_FOUND)\n");
            break;
        default:
            printf("\n");
            break;
        }
    }

    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 SendARP(
    DWORD DestIP,
    DWORD SrcIP,
    void* pMacAddr,
    DWORD* PhyAddrLen
);
[DllImport("IPHLPAPI.dll", ExactSpelling = true)]
static extern uint SendARP(
    uint DestIP,   // DWORD
    uint SrcIP,   // DWORD
    IntPtr pMacAddr,   // void* out
    ref uint PhyAddrLen   // DWORD* in/out
);
<DllImport("IPHLPAPI.dll", ExactSpelling:=True)>
Public Shared Function SendARP(
    DestIP As UInteger,   ' DWORD
    SrcIP As UInteger,   ' DWORD
    pMacAddr As IntPtr,   ' void* out
    ByRef PhyAddrLen As UInteger   ' DWORD* in/out
) As UInteger
End Function
' DestIP : DWORD
' SrcIP : DWORD
' pMacAddr : void* out
' PhyAddrLen : DWORD* in/out
Declare PtrSafe Function SendARP Lib "iphlpapi" ( _
    ByVal DestIP As Long, _
    ByVal SrcIP As Long, _
    ByVal pMacAddr As LongPtr, _
    ByRef PhyAddrLen As Long) As Long
' VBA7前提(PtrSafe)。32bit Office では LongPtr→Long。Integer=16bit / Long=32bit / LongLong=64bit。
import ctypes
from ctypes import wintypes

SendARP = ctypes.windll.iphlpapi.SendARP
SendARP.restype = wintypes.DWORD
SendARP.argtypes = [
    wintypes.DWORD,  # DestIP : DWORD
    wintypes.DWORD,  # SrcIP : DWORD
    ctypes.POINTER(None),  # pMacAddr : void* out
    ctypes.POINTER(wintypes.DWORD),  # PhyAddrLen : DWORD* in/out
]
require 'fiddle'
require 'fiddle/import'

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

var (
	iphlpapi = windows.NewLazySystemDLL("IPHLPAPI.dll")
	procSendARP = iphlpapi.NewProc("SendARP")
)

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

extern "iphlpapi" fn SendARP(
    DestIP: u32, // DWORD
    SrcIP: u32, // DWORD
    pMacAddr: ?*anyopaque, // void* out
    PhyAddrLen: [*c]u32 // DWORD* in/out
) callconv(std.os.windows.WINAPI) u32;
proc SendARP(
    DestIP: uint32,  # DWORD
    SrcIP: uint32,  # DWORD
    pMacAddr: pointer,  # void* out
    PhyAddrLen: ptr uint32  # DWORD* in/out
): uint32 {.importc: "SendARP", stdcall, dynlib: "IPHLPAPI.dll".}
pragma(lib, "iphlpapi");
extern(Windows)
uint SendARP(
    uint DestIP,   // DWORD
    uint SrcIP,   // DWORD
    void* pMacAddr,   // void* out
    uint* PhyAddrLen   // DWORD* in/out
);
ccall((:SendARP, "IPHLPAPI.dll"), stdcall, UInt32,
      (UInt32, UInt32, Ptr{Cvoid}, Ptr{UInt32}),
      DestIP, SrcIP, pMacAddr, PhyAddrLen)
# DestIP : DWORD -> UInt32
# SrcIP : DWORD -> UInt32
# pMacAddr : void* out -> Ptr{Cvoid}
# PhyAddrLen : DWORD* in/out -> Ptr{UInt32}
# stdcall は 32bit のみ意味を持つ(x64 では無視)。
local ffi = require("ffi")
ffi.cdef[[
uint32_t SendARP(
    uint32_t DestIP,
    uint32_t SrcIP,
    void* pMacAddr,
    uint32_t* PhyAddrLen);
]]
local iphlpapi = ffi.load("iphlpapi")
-- iphlpapi.SendARP(DestIP, SrcIP, pMacAddr, PhyAddrLen)
-- DestIP : DWORD
-- SrcIP : DWORD
-- pMacAddr : void* out
-- PhyAddrLen : DWORD* in/out
-- 構造体/GUIDへのポインタは cdef が通るよう void* で表記(実型は各引数コメント参照)。値渡し構造体・enum は対応する typedef を cdef に追加すること。
const koffi = require('koffi');
const lib = koffi.load('IPHLPAPI.dll');
const SendARP = lib.func('__stdcall', 'SendARP', 'uint32_t', ['uint32_t', 'uint32_t', 'void *', 'uint32_t *']);
// SendARP(DestIP, SrcIP, pMacAddr, PhyAddrLen)
// DestIP : DWORD -> 'uint32_t'
// SrcIP : DWORD -> 'uint32_t'
// pMacAddr : void* out -> 'void *'
// PhyAddrLen : DWORD* in/out -> 'uint32_t *'
// 出力ポインタは koffi.out(...) で包む。構造体は koffi.struct で定義。
const lib = Deno.dlopen("IPHLPAPI.dll", {
  SendARP: { parameters: ["u32", "u32", "pointer", "pointer"], result: "u32" },
});
// lib.symbols.SendARP(DestIP, SrcIP, pMacAddr, PhyAddrLen)
// DestIP : DWORD -> "u32"
// SrcIP : DWORD -> "u32"
// pMacAddr : void* out -> "pointer"
// PhyAddrLen : DWORD* in/out -> "pointer"
// 文字列引数は "buffer"(NUL 終端のバイト列を Uint8Array で渡す)。
// 値渡し構造体は { struct: [ ...field types... ] } を使用。
<?php
$ffi = FFI::cdef(<<<C
uint32_t SendARP(
    uint32_t DestIP,
    uint32_t SrcIP,
    void* pMacAddr,
    uint32_t* PhyAddrLen);
C, "IPHLPAPI.dll");
// $ffi->SendARP(DestIP, SrcIP, pMacAddr, PhyAddrLen);
// DestIP : DWORD
// SrcIP : DWORD
// pMacAddr : void* out
// PhyAddrLen : 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 SendARP(
        int DestIP,   // DWORD
        int SrcIP,   // DWORD
        Pointer pMacAddr,   // void* out
        IntByReference PhyAddrLen   // DWORD* in/out
    );
}
@[Link("iphlpapi")]
lib LibIPHLPAPI
  fun SendARP = SendARP(
    DestIP : UInt32,   # DWORD
    SrcIP : UInt32,   # DWORD
    pMacAddr : Void*,   # void* out
    PhyAddrLen : 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 SendARPNative = Uint32 Function(Uint32, Uint32, Pointer<Void>, Pointer<Uint32>);
typedef SendARPDart = int Function(int, int, Pointer<Void>, Pointer<Uint32>);
final SendARP = DynamicLibrary.open('IPHLPAPI.dll')
    .lookupFunction<SendARPNative, SendARPDart>('SendARP');
// DestIP : DWORD -> Uint32
// SrcIP : DWORD -> Uint32
// pMacAddr : void* out -> Pointer<Void>
// PhyAddrLen : DWORD* in/out -> Pointer<Uint32>
// 文字列は package:ffi の "...".toNativeUtf16()/toNativeUtf8() で変換。
{$mode objfpc}{$H+}
function SendARP(
  DestIP: DWORD;   // DWORD
  SrcIP: DWORD;   // DWORD
  pMacAddr: Pointer;   // void* out
  PhyAddrLen: Pointer   // DWORD* in/out
): DWORD; stdcall;
  external 'IPHLPAPI.dll' name 'SendARP';
import Foreign
import Foreign.C.Types
import Foreign.C.String

foreign import stdcall safe "SendARP"
  c_SendARP :: Word32 -> Word32 -> Ptr () -> Ptr Word32 -> IO Word32
-- DestIP : DWORD -> Word32
-- SrcIP : DWORD -> Word32
-- pMacAddr : void* out -> Ptr ()
-- PhyAddrLen : DWORD* in/out -> Ptr Word32
-- 要 GHC(Windows)。stdcall は x64 では ccall として扱われる。ブロックする API は safe 呼び出し推奨。
open Ctypes
open Foreign

let sendarp =
  foreign "SendARP"
    (uint32_t @-> uint32_t @-> (ptr void) @-> (ptr uint32_t) @-> returning uint32_t)
(* DestIP : DWORD -> uint32_t *)
(* SrcIP : DWORD -> uint32_t *)
(* pMacAddr : void* out -> (ptr void) *)
(* PhyAddrLen : 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 ("SendARP" send-arp :convention :stdcall) :uint32
  (dest-ip :uint32)   ; DWORD
  (src-ip :uint32)   ; DWORD
  (p-mac-addr :pointer)   ; void* out
  (phy-addr-len :pointer))   ; DWORD* in/out
; isize/usize(INT_PTR/SIZE_T)は x64 前提で :int64/:uint64。x86 では :int32/:uint32。
use Win32::API;
my $SendARP = Win32::API::More->new('IPHLPAPI',
    'DWORD SendARP(DWORD DestIP, DWORD SrcIP, LPVOID pMacAddr, LPVOID PhyAddrLen)');
# my $ret = $SendARP->Call($DestIP, $SrcIP, $pMacAddr, $PhyAddrLen);
# DestIP : DWORD -> DWORD
# SrcIP : DWORD -> DWORD
# pMacAddr : void* out -> LPVOID
# PhyAddrLen : DWORD* in/out -> LPVOID
# 値渡し構造体は pack() した文字列、または Win32::API::Struct を使用。

関連項目

公式の関連項目