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

GetNameInfoW

関数
ソケットアドレスからホスト名とサービス名をUnicodeで取得する。
DLLWS2_32.dll呼出規約winapi対応OSWindows 8.1 以降

シグネチャ

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

INT GetNameInfoW(
    const SOCKADDR* pSockaddr,
    socklen_t SockaddrLength,
    LPWSTR pNodeBuffer,   // optional
    DWORD NodeBufferSize,
    LPWSTR pServiceBuffer,   // optional
    DWORD ServiceBufferSize,
    INT Flags
);

パラメーター

名前方向説明
pSockaddrSOCKADDR*inソケットの IP アドレスとポート番号を含むソケットアドレス構造体へのポインターです。IPv4 の場合、pSockaddr パラメーターは sockaddr_in 構造体を指します。IPv6 の場合、pSockaddr パラメーターは sockaddr_in6 構造体を指します。
SockaddrLengthsocklen_tinpSockaddr パラメーターが指す構造体の長さ(バイト単位)です。
pNodeBufferLPWSTRoutoptionalホスト名を格納する Unicode 文字列へのポインターです。成功した場合、既定では完全修飾ドメイン名 (FQDN) として Unicode ホスト名へのポインターが返されます。pNodeBuffer パラメーターが NULL の場合、呼び出し元がホスト名文字列の受け取りを希望しないことを示します。
NodeBufferSizeDWORDinpNodeBuffer パラメーターが指すバッファー内の WCHAR 文字数です。呼び出し元は、終端の NULL 文字を含む Unicode ホスト名を格納できる十分な大きさのバッファーを用意する必要があります。
pServiceBufferLPWSTRoutoptionalサービス名を格納する Unicode 文字列へのポインターです。成功した場合、ポート番号に関連付けられたサービス名を表す Unicode 文字列へのポインターが返されます。pServiceBuffer パラメーターが NULL の場合、呼び出し元がサービス名文字列の受け取りを希望しないことを示します。
ServiceBufferSizeDWORDinpServiceBuffer パラメーターが指すバッファー内の WCHAR 文字数です。呼び出し元は、終端の NULL 文字を含む Unicode サービス名を格納できる十分な大きさのバッファーを用意する必要があります。
FlagsINTinGetNameInfoW 関数の処理をカスタマイズするために使用される値です。「解説」セクションを参照してください。

戻り値の型: INT

公式ドキュメント

プロトコルに依存しない名前解決を提供し、アドレスから Unicode ホスト名へ、ポート番号から Unicode サービス名へ変換します。

戻り値

成功した場合、GetNameInfoW はゼロを返します。ゼロ以外の戻り値はいずれも失敗を示し、 WSAGetLastError を呼び出すことで特定のエラーコードを取得できます。

GetNameInfoW 関数が返すゼロ以外のエラーコードは、Internet Engineering Task Force (IETF) の推奨事項で示されているエラーのセットにも対応します。次の表に、これらのエラーコードとそれに相当する WSA のエラーコードを示します。WSA のエラーコードは、Winsock プログラマーにとって馴染みがあり包括的なエラー情報を提供するため、こちらを使用することを推奨します。

エラー値 WSA の相当値 説明
EAI_AGAIN WSATRY_AGAIN 名前解決で一時的な失敗が発生しました。
EAI_BADFLAGS WSAEINVAL 1 つ以上の無効なパラメーターが GetNameInfoW 関数に渡されました。このエラーは、ホスト名が要求されたが NodeBufferSize パラメーターがゼロであった場合、またはサービス名が要求されたが ServiceBufferSize パラメーターがゼロであった場合に返されます。
EAI_FAIL WSANO_RECOVERY 名前解決で回復不可能な失敗が発生しました。
EAI_FAMILY WSAEAFNOSUPPORT pSockaddr パラメーターが指すソケットアドレス構造体の sa_family メンバーがサポートされていません。
EAI_MEMORY WSA_NOT_ENOUGH_MEMORY メモリの割り当てに失敗しました。
EAI_NONAME WSAHOST_NOT_FOUND サービス名が要求されましたが、pSockaddr パラメーターが指す構造体にポート番号が見つからなかったか、ポート番号に一致するサービス名が見つかりませんでした。NI_NAMEREQD が設定されていてホスト名を特定できない場合、または pNodeBufferpServiceBuffer の両パラメーターが NULL であった場合です。

gai_strerror 関数を使用すると、GetNameInfoW 関数が返す EAI コードに基づいてエラーメッセージを出力できます。 gai_strerror 関数は IETF の推奨事項に準拠するために提供されていますが、スレッドセーフではありません。そのため、 WSAGetLastError などの従来の Windows Sockets 関数を使用することを推奨します。

さらに、次のエラーコードが返される場合があります。

エラーコード 意味
WSAEFAULT
このエラーは、pSockaddr パラメーターが NULL の場合、または SockaddrLength パラメーターが IPv4 用の sockaddr_in 構造体や IPv6 用の sockaddr_in6 構造体のサイズに必要な長さよりも小さい場合に返されます。

解説(Remarks)

GetNameInfoW 関数は、プロトコルに依存しない名前解決を提供する関数の Unicode 版です。GetNameInfoW 関数は、ソケットアドレス構造体の内容をノード名やサービス名に変換するために使用されます。

IPv6 および IPv4 プロトコルでは、名前解決はドメインネームシステム (DNS)、ローカルの hosts ファイル、またはその他の命名メカニズムによって行われます。この関数は、IPv4 または IPv6 アドレスのホスト名の特定(逆引き DNS 検索)や、ポート番号のサービス名の特定に使用できます。GetNameInfoW 関数は、SOCKADDR 構造体内の IP アドレスやポート番号を Unicode 文字列に変換するためにも使用できます。また、ホスト名の IP アドレスを特定するためにも使用できます。

この関数の ANSI 版は getnameinfo です。

Winsock ヘッダーファイル内のマクロは、アプリケーションが Windows XP Service Pack 2 (SP2) 以降 (_WIN32_WINNT >= 0x0502) を対象とする場合に使用できる、大文字と小文字が混在した関数名 GetNameInfo を定義しています。この GetNameInfo 関数は、pNodeBuffer および pServiceBuffer パラメーターを TCHAR 型のポインターとして呼び出す必要があります。UNICODE または _UNICODE が定義されている場合、GetNameInfo は Unicode 版として定義され、host および serv パラメーターを char 型のポインターとして GetNameInfoW が呼び出されます。UNICODE または _UNICODE が定義されていない場合、GetNameInfo は ANSI 版として定義され、pNodeBuffer および pServiceBuffer パラメーターを PWCHAR 型のポインターとして getnameinfo が呼び出されます。

pNodeBuffer および pServiceBuffer パラメーターのバッファー要件の判断を簡単にするため、最大ホスト名長と最大サービス名長として次の値が Ws2tcpip.h ヘッダーファイルに定義されています。

#include <windows.h>

#define NI_MAXSERV    32
#define NI_MAXHOST  1025

Flags パラメーターは、 GetNameInfoW 関数の処理をカスタマイズするために使用できます。次のフラグが使用できます。

NI_NAMEREQD フラグが設定されている場合、DNS で解決できないホスト名はエラーになります。

NI_NOFQDN フラグを設定すると、ローカルホストについては相対識別名 (RDN) のみが pNodeBuffer パラメーターに返されます。

NI_NUMERICHOST フラグを設定すると、ホスト名の代わりにその数値形式が返されます。ホスト名が DNS で解決できない場合も、数値形式が返されます。

NI_NUMERICSERV フラグを設定すると、サービス名の代わりにそのポート番号が返されます。また、IP アドレス(例: 127.0.0.2)に対してホスト名が見つからない場合、ホスト名としてその IP アドレスが返されます。

Windows Vista 以降では、flags パラメーターに NI_NUMERICSERV が指定されておらず、sa パラメーターが指す sockaddr 構造体に含まれるポート番号がよく知られたサービスに解決できない場合、GetNameInfoW 関数はサービスアドレス(ポート番号)の数値形式を数値文字列として返します。NI_NUMERICSERV が指定されている場合、ポート番号は数値文字列として返されます。この動作は RFC 3493 の 6.2 節で規定されています。詳細については、www.ietf.org/rfc/rfc3493.txt を参照してください。

Windows Server 2003 以前では、flags パラメーターに NI_NUMERICSERV が指定されておらず、sa パラメーターが指す sockaddr 構造体に含まれるポート番号がよく知られたサービスに解決できない場合、GetNameInfoW 関数は失敗します。NI_NUMERICSERV が指定されている場合、ポート番号は数値文字列として返されます。

NI_DGRAM フラグを設定すると、サービスがデータグラムサービスであることを示します。このフラグは、UDP と TCP のサービスで異なるポート番号を提供する少数のサービスにとって必要です。

注意 GetNameInfoW 関数を使用して逆引き DNS 検索を実行できる機能は便利ですが、そのような検索は本質的に信頼性が低いと見なされており、ヒントとしてのみ使用すべきです。
注意 GetNameInfoW はエイリアス名の解決には使用できません。

Windows Phone 8: この関数は、Windows Phone 8 以降の Windows Phone ストアアプリでサポートされています。

Windows 8.1 および Windows Server 2012 R2: この関数は、Windows 8.1、Windows Server 2012 R2 以降の Windows ストアアプリでサポートされています。

サンプルコード

次の例は、GetNameInfoW 関数の使用方法を示しています。
#ifndef UNICODE
#define UNICODE
#endif

#define WIN32_LEAN_AND_MEAN

#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;

    DWORD dwRetval;

    struct sockaddr_in saGNI;
    WCHAR hostname[NI_MAXHOST];
    WCHAR servInfo[NI_MAXSERV];
    u_short port = 27015;

    // Validate the parameters
    if (argc != 2) {
        wprintf(L"usage: %s IPv4 address\n", argv[0]);
        wprintf(L"  to return hostname\n");
        wprintf(L"       %s 127.0.0.1\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;
    }
    //-----------------------------------------
    // Set up sockaddr_in structure which is passed
    // to the getnameinfo function
    saGNI.sin_family = AF_INET;
    saGNI.sin_addr.s_addr = inet_addr(argv[1]);
    saGNI.sin_port = htons(port);

    //-----------------------------------------
    // Call GetNameInfoW
    dwRetval = GetNameInfoW((struct sockaddr *) &saGNI,
                           sizeof (struct sockaddr),
                           hostname,
                           NI_MAXHOST, servInfo, NI_MAXSERV, NI_NUMERICSERV);

    if (dwRetval != 0) {
        wprintf(L"GetNameInfoW failed with error # %ld\n", WSAGetLastError());
        return 1;
    } else {
        wprintf(L"GetNameInfoW returned hostname = %ws\n", hostname);
        return 0;
    }
}
メモ

ws2tcpip.h ヘッダーは、UNICODE プリプロセッサ定数の定義に基づいてこの関数の ANSI 版または Unicode 版を自動的に選択するエイリアスとして GetNameInfo を定義します。エンコーディング中立のエイリアスの使用を、エンコーディング中立でないコードと混在させると、コンパイルエラーや実行時エラーを引き起こす不一致が生じる可能性があります。詳細については、関数プロトタイプの規則 を参照してください。

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

各言語での呼び出し定義

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

INT GetNameInfoW(
    const SOCKADDR* pSockaddr,
    socklen_t SockaddrLength,
    LPWSTR pNodeBuffer,   // optional
    DWORD NodeBufferSize,
    LPWSTR pServiceBuffer,   // optional
    DWORD ServiceBufferSize,
    INT Flags
);
[DllImport("WS2_32.dll", ExactSpelling = true)]
static extern int GetNameInfoW(
    IntPtr pSockaddr,   // SOCKADDR*
    int SockaddrLength,   // socklen_t
    [MarshalAs(UnmanagedType.LPWStr)] System.Text.StringBuilder pNodeBuffer,   // LPWSTR optional, out
    uint NodeBufferSize,   // DWORD
    [MarshalAs(UnmanagedType.LPWStr)] System.Text.StringBuilder pServiceBuffer,   // LPWSTR optional, out
    uint ServiceBufferSize,   // DWORD
    int Flags   // INT
);
<DllImport("WS2_32.dll", ExactSpelling:=True)>
Public Shared Function GetNameInfoW(
    pSockaddr As IntPtr,   ' SOCKADDR*
    SockaddrLength As Integer,   ' socklen_t
    <MarshalAs(UnmanagedType.LPWStr)> pNodeBuffer As System.Text.StringBuilder,   ' LPWSTR optional, out
    NodeBufferSize As UInteger,   ' DWORD
    <MarshalAs(UnmanagedType.LPWStr)> pServiceBuffer As System.Text.StringBuilder,   ' LPWSTR optional, out
    ServiceBufferSize As UInteger,   ' DWORD
    Flags As Integer   ' INT
) As Integer
End Function
' pSockaddr : SOCKADDR*
' SockaddrLength : socklen_t
' pNodeBuffer : LPWSTR optional, out
' NodeBufferSize : DWORD
' pServiceBuffer : LPWSTR optional, out
' ServiceBufferSize : DWORD
' Flags : INT
Declare PtrSafe Function GetNameInfoW Lib "ws2_32" ( _
    ByVal pSockaddr As LongPtr, _
    ByVal SockaddrLength As Long, _
    ByVal pNodeBuffer As LongPtr, _
    ByVal NodeBufferSize As Long, _
    ByVal pServiceBuffer As LongPtr, _
    ByVal ServiceBufferSize As Long, _
    ByVal Flags As Long) As Long
' VBA7前提(PtrSafe)。32bit Office では LongPtr→Long。Integer=16bit / Long=32bit / LongLong=64bit。
import ctypes
from ctypes import wintypes

GetNameInfoW = ctypes.windll.ws2_32.GetNameInfoW
GetNameInfoW.restype = ctypes.c_int
GetNameInfoW.argtypes = [
    ctypes.c_void_p,  # pSockaddr : SOCKADDR*
    ctypes.c_int,  # SockaddrLength : socklen_t
    wintypes.LPWSTR,  # pNodeBuffer : LPWSTR optional, out
    wintypes.DWORD,  # NodeBufferSize : DWORD
    wintypes.LPWSTR,  # pServiceBuffer : LPWSTR optional, out
    wintypes.DWORD,  # ServiceBufferSize : DWORD
    ctypes.c_int,  # Flags : INT
]
require 'fiddle'
require 'fiddle/import'

lib = Fiddle.dlopen('WS2_32.dll')
GetNameInfoW = Fiddle::Function.new(
  lib['GetNameInfoW'],
  [
    Fiddle::TYPE_VOIDP,  # pSockaddr : SOCKADDR*
    Fiddle::TYPE_INT,  # SockaddrLength : socklen_t
    Fiddle::TYPE_VOIDP,  # pNodeBuffer : LPWSTR optional, out
    -Fiddle::TYPE_INT,  # NodeBufferSize : DWORD
    Fiddle::TYPE_VOIDP,  # pServiceBuffer : LPWSTR optional, out
    -Fiddle::TYPE_INT,  # ServiceBufferSize : DWORD
    Fiddle::TYPE_INT,  # Flags : INT
  ],
  Fiddle::TYPE_INT)
#[link(name = "ws2_32")]
extern "system" {
    fn GetNameInfoW(
        pSockaddr: *const SOCKADDR,  // SOCKADDR*
        SockaddrLength: i32,  // socklen_t
        pNodeBuffer: *mut u16,  // LPWSTR optional, out
        NodeBufferSize: u32,  // DWORD
        pServiceBuffer: *mut u16,  // LPWSTR optional, out
        ServiceBufferSize: u32,  // DWORD
        Flags: i32  // INT
    ) -> i32;
}
// crates: windows-sys provides ready-made bindings for this API.
$sig = @"
[DllImport("WS2_32.dll")]
public static extern int GetNameInfoW(IntPtr pSockaddr, int SockaddrLength, [MarshalAs(UnmanagedType.LPWStr)] System.Text.StringBuilder pNodeBuffer, uint NodeBufferSize, [MarshalAs(UnmanagedType.LPWStr)] System.Text.StringBuilder pServiceBuffer, uint ServiceBufferSize, int Flags);
"@
$api = Add-Type -MemberDefinition $sig -Name 'WS2_32_GetNameInfoW' -Namespace Win32 -PassThru
# $api::GetNameInfoW(pSockaddr, SockaddrLength, pNodeBuffer, NodeBufferSize, pServiceBuffer, ServiceBufferSize, Flags)
#uselib "WS2_32.dll"
#func global GetNameInfoW "GetNameInfoW" sptr, sptr, sptr, sptr, sptr, sptr, sptr
; GetNameInfoW varptr(pSockaddr), SockaddrLength, varptr(pNodeBuffer), NodeBufferSize, varptr(pServiceBuffer), ServiceBufferSize, Flags   ; 戻り値は stat
; pSockaddr : SOCKADDR* -> "sptr"
; SockaddrLength : socklen_t -> "sptr"
; pNodeBuffer : LPWSTR optional, out -> "sptr"
; NodeBufferSize : DWORD -> "sptr"
; pServiceBuffer : LPWSTR optional, out -> "sptr"
; ServiceBufferSize : DWORD -> "sptr"
; Flags : INT -> "sptr"
; ※HSP3.7は #func のため戻り値はシステム変数 stat に格納されます。
出力引数:
#uselib "WS2_32.dll"
#cfunc global GetNameInfoW "GetNameInfoW" var, int, var, int, var, int, int
; res = GetNameInfoW(pSockaddr, SockaddrLength, pNodeBuffer, NodeBufferSize, pServiceBuffer, ServiceBufferSize, Flags)
; pSockaddr : SOCKADDR* -> "var"
; SockaddrLength : socklen_t -> "int"
; pNodeBuffer : LPWSTR optional, out -> "var"
; NodeBufferSize : DWORD -> "int"
; pServiceBuffer : LPWSTR optional, out -> "var"
; ServiceBufferSize : DWORD -> "int"
; Flags : INT -> "int"
; ※出力/バッファ引数は var 方式(変数を直接渡す)。varptr 方式にも切替可。
出力引数:
; INT GetNameInfoW(SOCKADDR* pSockaddr, socklen_t SockaddrLength, LPWSTR pNodeBuffer, DWORD NodeBufferSize, LPWSTR pServiceBuffer, DWORD ServiceBufferSize, INT Flags)
#uselib "WS2_32.dll"
#cfunc global GetNameInfoW "GetNameInfoW" var, int, var, int, var, int, int
; res = GetNameInfoW(pSockaddr, SockaddrLength, pNodeBuffer, NodeBufferSize, pServiceBuffer, ServiceBufferSize, Flags)
; pSockaddr : SOCKADDR* -> "var"
; SockaddrLength : socklen_t -> "int"
; pNodeBuffer : LPWSTR optional, out -> "var"
; NodeBufferSize : DWORD -> "int"
; pServiceBuffer : LPWSTR optional, out -> "var"
; ServiceBufferSize : DWORD -> "int"
; Flags : INT -> "int"
; ※出力/バッファ引数は var 方式(変数を直接渡す)。varptr 方式にも切替可。
import (
	"golang.org/x/sys/windows"
	"unsafe"
)

var (
	ws2_32 = windows.NewLazySystemDLL("WS2_32.dll")
	procGetNameInfoW = ws2_32.NewProc("GetNameInfoW")
)

// pSockaddr (SOCKADDR*), SockaddrLength (socklen_t), pNodeBuffer (LPWSTR optional, out), NodeBufferSize (DWORD), pServiceBuffer (LPWSTR optional, out), ServiceBufferSize (DWORD), Flags (INT)
r1, _, err := procGetNameInfoW.Call(
	uintptr(pSockaddr),
	uintptr(SockaddrLength),
	uintptr(pNodeBuffer),
	uintptr(NodeBufferSize),
	uintptr(pServiceBuffer),
	uintptr(ServiceBufferSize),
	uintptr(Flags),
)
_ = err  // syscall.Errno (valid when the call sets last-error)
_ = r1   // INT
function GetNameInfoW(
  pSockaddr: Pointer;   // SOCKADDR*
  SockaddrLength: Integer;   // socklen_t
  pNodeBuffer: PWideChar;   // LPWSTR optional, out
  NodeBufferSize: DWORD;   // DWORD
  pServiceBuffer: PWideChar;   // LPWSTR optional, out
  ServiceBufferSize: DWORD;   // DWORD
  Flags: Integer   // INT
): Integer; stdcall;
  external 'WS2_32.dll' name 'GetNameInfoW';
result := DllCall("WS2_32\GetNameInfoW"
    , "Ptr", pSockaddr   ; SOCKADDR*
    , "Int", SockaddrLength   ; socklen_t
    , "Ptr", pNodeBuffer   ; LPWSTR optional, out
    , "UInt", NodeBufferSize   ; DWORD
    , "Ptr", pServiceBuffer   ; LPWSTR optional, out
    , "UInt", ServiceBufferSize   ; DWORD
    , "Int", Flags   ; INT
    , "Int")   ; return: INT
●GetNameInfoW(pSockaddr, SockaddrLength, pNodeBuffer, NodeBufferSize, pServiceBuffer, ServiceBufferSize, Flags) = DLL("WS2_32.dll", "int GetNameInfoW(void*, int, char*, dword, char*, dword, int)")
# 呼び出し: GetNameInfoW(pSockaddr, SockaddrLength, pNodeBuffer, NodeBufferSize, pServiceBuffer, ServiceBufferSize, Flags)
# pSockaddr : SOCKADDR* -> "void*"
# SockaddrLength : socklen_t -> "int"
# pNodeBuffer : LPWSTR optional, out -> "char*"
# NodeBufferSize : DWORD -> "dword"
# pServiceBuffer : LPWSTR optional, out -> "char*"
# ServiceBufferSize : DWORD -> "dword"
# Flags : INT -> "int"
# なでしこ1は32bit・ANSI(Shift_JIS)。文字列=char*(ANSI)、ポインタ/ハンドル=void*(4byte)。
const std = @import("std");

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

typedef GetNameInfoWNative = Int32 Function(Pointer<Void>, Int32, Pointer<Utf16>, Uint32, Pointer<Utf16>, Uint32, Int32);
typedef GetNameInfoWDart = int Function(Pointer<Void>, int, Pointer<Utf16>, int, Pointer<Utf16>, int, int);
final GetNameInfoW = DynamicLibrary.open('WS2_32.dll')
    .lookupFunction<GetNameInfoWNative, GetNameInfoWDart>('GetNameInfoW');
// pSockaddr : SOCKADDR* -> Pointer<Void>
// SockaddrLength : socklen_t -> Int32
// pNodeBuffer : LPWSTR optional, out -> Pointer<Utf16>
// NodeBufferSize : DWORD -> Uint32
// pServiceBuffer : LPWSTR optional, out -> Pointer<Utf16>
// ServiceBufferSize : DWORD -> Uint32
// Flags : INT -> Int32
// 文字列は package:ffi の "...".toNativeUtf16()/toNativeUtf8() で変換。
{$mode objfpc}{$H+}
function GetNameInfoW(
  pSockaddr: Pointer;   // SOCKADDR*
  SockaddrLength: Integer;   // socklen_t
  pNodeBuffer: PWideChar;   // LPWSTR optional, out
  NodeBufferSize: DWORD;   // DWORD
  pServiceBuffer: PWideChar;   // LPWSTR optional, out
  ServiceBufferSize: DWORD;   // DWORD
  Flags: Integer   // INT
): Integer; stdcall;
  external 'WS2_32.dll' name 'GetNameInfoW';
import Foreign
import Foreign.C.Types
import Foreign.C.String

foreign import stdcall safe "GetNameInfoW"
  c_GetNameInfoW :: Ptr () -> Int32 -> CWString -> Word32 -> CWString -> Word32 -> Int32 -> IO Int32
-- pSockaddr : SOCKADDR* -> Ptr ()
-- SockaddrLength : socklen_t -> Int32
-- pNodeBuffer : LPWSTR optional, out -> CWString
-- NodeBufferSize : DWORD -> Word32
-- pServiceBuffer : LPWSTR optional, out -> CWString
-- ServiceBufferSize : DWORD -> Word32
-- Flags : INT -> Int32
-- 要 GHC(Windows)。stdcall は x64 では ccall として扱われる。ブロックする API は safe 呼び出し推奨。
open Ctypes
open Foreign

let getnameinfow =
  foreign "GetNameInfoW"
    ((ptr void) @-> int32_t @-> (ptr uint16_t) @-> uint32_t @-> (ptr uint16_t) @-> uint32_t @-> int32_t @-> returning int32_t)
(* pSockaddr : SOCKADDR* -> (ptr void) *)
(* SockaddrLength : socklen_t -> int32_t *)
(* pNodeBuffer : LPWSTR optional, out -> (ptr uint16_t) *)
(* NodeBufferSize : DWORD -> uint32_t *)
(* pServiceBuffer : LPWSTR optional, out -> (ptr uint16_t) *)
(* ServiceBufferSize : DWORD -> uint32_t *)
(* Flags : INT -> int32_t *)
(* foreign は cdecl 前提。x64 Windows では WINAPI と一致。構造体は ctypes structure を定義のこと。 *)
(cffi:define-foreign-library ws2_32 (t "WS2_32.dll"))
(cffi:use-foreign-library ws2_32)

(cffi:defcfun ("GetNameInfoW" get-name-info-w :convention :stdcall) :int32
  (p-sockaddr :pointer)   ; SOCKADDR*
  (sockaddr-length :int32)   ; socklen_t
  (p-node-buffer :pointer)   ; LPWSTR optional, out
  (node-buffer-size :uint32)   ; DWORD
  (p-service-buffer :pointer)   ; LPWSTR optional, out
  (service-buffer-size :uint32)   ; DWORD
  (flags :int32))   ; INT
; isize/usize(INT_PTR/SIZE_T)は x64 前提で :int64/:uint64。x86 では :int32/:uint32。
use Win32::API;
my $GetNameInfoW = Win32::API::More->new('WS2_32',
    'int GetNameInfoW(LPVOID pSockaddr, int SockaddrLength, LPWSTR pNodeBuffer, DWORD NodeBufferSize, LPWSTR pServiceBuffer, DWORD ServiceBufferSize, int Flags)');
# my $ret = $GetNameInfoW->Call($pSockaddr, $SockaddrLength, $pNodeBuffer, $NodeBufferSize, $pServiceBuffer, $ServiceBufferSize, $Flags);
# pSockaddr : SOCKADDR* -> LPVOID
# SockaddrLength : socklen_t -> int
# pNodeBuffer : LPWSTR optional, out -> LPWSTR
# NodeBufferSize : DWORD -> DWORD
# pServiceBuffer : LPWSTR optional, out -> LPWSTR
# ServiceBufferSize : DWORD -> DWORD
# Flags : INT -> int
# 値渡し構造体は pack() した文字列、または Win32::API::Struct を使用。

関連項目

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