getnameinfo
関数シグネチャ
// WS2_32.dll
#include <windows.h>
INT getnameinfo(
const SOCKADDR* pSockaddr,
socklen_t SockaddrLength,
LPSTR pNodeBuffer, // optional
DWORD NodeBufferSize,
LPSTR pServiceBuffer, // optional
DWORD ServiceBufferSize,
INT Flags
);パラメーター
| 名前 | 型 | 方向 | 説明 |
|---|---|---|---|
| pSockaddr | SOCKADDR* | in | ソケットのアドレスとポート番号を格納したソケットアドレス構造体へのポインターです。IPv4 の場合、sa パラメーターは sockaddr_in 構造体を指します。IPv6 の場合、sa パラメーターは sockaddr_in6 構造体を指します。 |
| SockaddrLength | socklen_t | in | sa パラメーターが指す構造体の長さ(バイト単位)です。 |
| pNodeBuffer | LPSTR | outoptional | ホスト名を格納するために使用される ANSI 文字列へのポインターです。成功した場合、既定ではホスト名は完全修飾ドメイン名 (FQDN) として返されます。host パラメーターが NULL の場合、呼び出し側がホスト名文字列の受け取りを希望しないことを示します。 |
| NodeBufferSize | DWORD | in | host パラメーターが指すバッファーの長さ(バイト単位)です。呼び出し側は、終端の NULL 文字を含めてホスト名を格納できる十分な大きさのバッファーを用意する必要があります。 |
| pServiceBuffer | LPSTR | outoptional | サービス名を格納するための ANSI 文字列へのポインターです。成功した場合、ポート番号に関連付けられたサービス名を表す ANSI 文字列が返されます。serv パラメーターが NULL の場合、呼び出し側がサービス名文字列の受け取りを希望しないことを示します。 |
| ServiceBufferSize | DWORD | in | serv パラメーターが指すバッファーの長さ(バイト単位)です。呼び出し側は、終端の NULL 文字を含めてサービス名を格納できる十分な大きさのバッファーを用意する必要があります。 |
| Flags | INT | in | getnameinfo 関数の処理をカスタマイズするために使用する値です。「解説」セクションを参照してください。 |
戻り値の型: INT
公式ドキュメント
アドレスから ANSI ホスト名へ、およびポート番号から ANSI サービス名へ、プロトコルに依存しない名前解決を提供します。
戻り値
成功すると、getnameinfo は 0 を返します。0 以外の戻り値はすべて失敗を示し、 WSAGetLastError を呼び出すことで特定のエラーコードを取得できます。
getnameinfo 関数が返す 0 以外のエラーコードは、Internet Engineering Task Force (IETF) の勧告で定められた一連のエラーにも対応しています。次の表に、これらのエラーコードとそれに対応する WSA の同等コードを示します。WSA エラーコードは Winsock プログラマーにとってなじみがあり包括的なエラー情報を提供するため、WSA エラーコードの使用が推奨されます。
| エラー値 | WSA の同等コード | 説明 |
|---|---|---|
| EAI_AGAIN | WSATRY_AGAIN | 名前解決で一時的な失敗が発生しました。 |
| EAI_BADFLAGS | WSAEINVAL | 1 つ以上の無効なパラメーターが getnameinfo 関数に渡されました。このエラーは、ホスト名が要求されたが hostlen パラメーターが 0 であった場合、またはサービス名が要求されたが servlen パラメーターが 0 であった場合に返されます。 |
| EAI_FAIL | WSANO_RECOVERY | 名前解決で回復不能な失敗が発生しました。 |
| EAI_FAMILY | WSAEAFNOSUPPORT | sa パラメーターが指すソケットアドレス構造体の sa_family メンバーがサポートされていません。 |
| EAI_MEMORY | WSA_NOT_ENOUGH_MEMORY | メモリ割り当ての失敗が発生しました。 |
| EAI_NONAME | WSAHOST_NOT_FOUND | サービス名が要求されたが、sa パラメーターが指す構造体にポート番号が見つからなかったか、ポート番号に一致するサービス名が見つかりませんでした。NI_NAMEREQD が設定されていてホスト名を特定できない場合、または host パラメーターと serv パラメーターの両方が NULL であった場合に返されます。 |
getnameinfo 関数が返す EAI コードに基づいてエラーメッセージを出力するには、 gai_strerror 関数を使用します。 gai_strerror 関数は IETF の勧告への準拠のために提供されていますが、スレッドセーフではありません。そのため、 WSAGetLastError などの従来の Windows Sockets 関数の使用が推奨されます。
さらに、次のエラーコードが返される場合があります。
| エラーコード | 意味 |
|---|---|
| このエラーは、sa パラメーターが NULL である場合、または salen パラメーターが IPv4 用の sockaddr_in 構造体もしくは IPv6 用の sockaddr_in6 構造体のサイズに必要な長さより小さい場合に返されます。 |
解説(Remarks)
getnameinfo 関数は、プロトコルに依存しない名前解決を提供する関数の ANSI バージョンです。getnameinfo 関数は、ソケットアドレス構造体の内容をノード名やサービス名に変換するために使用されます。
IPv6 および IPv4 プロトコルでは、名前解決はドメインネームシステム (DNS)、ローカルの hosts ファイル、またはその他の名前付けメカニズムによって行われます。この関数は、IPv4 または IPv6 アドレスのホスト名を特定する(逆引き DNS 検索)、あるいはポート番号のサービス名を特定するために使用できます。getnameinfo 関数は、sockaddr 構造体内の IP アドレスやポート番号を ANSI 文字列に変換するためにも使用できます。また、この関数はホスト名から IP アドレスを特定するためにも使用できます。
getnameinfo 関数の別名として GetNameInfoA を使用できます。Ws2tcpip.h ヘッダーファイル内のマクロにより、GetNameInfoA は getnameinfo として定義されています。
Windows XP Service Pack 2 (SP2) 以降で利用可能なこの関数の Unicode バージョンは GetNameInfoW です。
Winsock ヘッダーファイル内のマクロは、GetNameInfo という大文字と小文字が混在した関数名を定義しており、アプリケーションが Windows XP SP2 以降 (_WIN32_WINNT >= 0x0502) を対象とする場合に使用できます。この GetNameInfo 関数は、host パラメーターと serv パラメーターに TCHAR 型のポインターを指定して呼び出します。UNICODE または _UNICODE が定義されていない場合、GetNameInfo は ANSI バージョンとして定義され、host パラメーターと serv パラメーターに char 型のポインターを指定して getnameinfo が呼び出されます。UNICODE または _UNICODE が定義されている場合、GetNameInfo は Unicode バージョンとして定義され、pNodeBuffer パラメーターと pServiceBuffer パラメーターに PWCHAR 型のポインターを指定して GetNameInfoW が呼び出されます。
host パラメーターと serv パラメーターのバッファー要件の決定を簡単にするため、最大ホスト名長と最大サービス名長の値が Ws2tcpip.h ヘッダーファイルに次のように定義されています。
#define NI_MAXSERV 32
#define NI_MAXHOST 1025
flags パラメーターは、 getnameinfo 関数の処理をカスタマイズするために使用できます。次のフラグが利用できます。
NI_NAMEREQD フラグが設定されている場合、DNS で解決できないホスト名はエラーになります。
NI_NOFQDN フラグを設定すると、ローカルホストについては host パラメーターにその相対識別名 (RDN) のみが返されます。
NI_NUMERICHOST フラグを設定すると、ホスト名の代わりにその数値形式が返されます。ホスト名が DNS で解決できない場合も、ホスト名の数値形式が返されます。
NI_NUMERICSERV フラグを設定すると、サービス名の代わりにそのポート番号が返されます。また、IP アドレス(たとえば 127.0.0.2)に対してホスト名が見つからない場合、ホスト名はその IP アドレスとして返されます。
Windows Vista 以降では、flags パラメーターに NI_NUMERICSERV が指定されておらず、sa パラメーターが指す sockaddr 構造体に含まれるポート番号が既知のサービスに解決されない場合、getnameinfo 関数はサービスアドレス(ポート番号)の数値形式を数値文字列として返します。NI_NUMERICSERV が指定されている場合、ポート番号は数値文字列として返されます。この動作は RFC 3493 のセクション 6.2 で規定されています。詳細については、www.ietf.org/rfc3493.txt を参照してください。
Windows Server 2003 以前では、flags パラメーターに NI_NUMERICSERV が指定されておらず、sa パラメーターが指す sockaddr 構造体に含まれるポート番号が既知のサービスに解決されない場合、getnameinfo 関数は失敗します。NI_NUMERICSERV が指定されている場合、ポート番号は数値文字列として返されます。
NI_DGRAM フラグを設定すると、サービスがデータグラムサービスであることを示します。このフラグは、UDP サービスと TCP サービスで異なるポート番号を提供する少数のサービスに必要です。
サンプルコード
次のコード例は、getnameinfo 関数の使用方法を示しています。#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 = {0};
int iResult = 0;
DWORD dwRetval;
struct sockaddr_in saGNI;
char hostname[NI_MAXHOST];
char servInfo[NI_MAXSERV];
u_short port = 27015;
// Validate the parameters
if (argc != 2) {
printf("usage: %s IPv4 address\n", argv[0]);
printf(" to return hostname\n");
printf(" %s 127.0.0.1\n", argv[0]);
return 1;
}
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0) {
printf("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 getnameinfo
dwRetval = getnameinfo((struct sockaddr *) &saGNI,
sizeof (struct sockaddr),
hostname,
NI_MAXHOST, servInfo, NI_MAXSERV, NI_NUMERICSERV);
if (dwRetval != 0) {
printf("getnameinfo failed with error # %ld\n", WSAGetLastError());
return 1;
} else {
printf("getnameinfo returned hostname = %s\n", hostname);
return 0;
}
}
古いバージョンの Windows での getnameinfo のサポート
getnameinfo 関数は Windows XP 以降の Ws2_32.dll に追加されました。この関数を使用するアプリケーションを以前のバージョンの Windows (Windows 2000、Windows NT、Windows Me/98/95) で実行したい場合は、Ws2tcpip.h ファイルに加えて Wspiapi.h ファイルもインクルードする必要があります。Wspiapi.h インクルードファイルが追加されると、getnameinfo 関数は Wspiapi.h ファイル内の WspiapiGetNameInfo インライン関数として定義されます。実行時には、Ws2_32.dll または Wship6.dll(Windows 2000 向け IPv6 Technology Preview で getnameinfo を含むファイル)が getnameinfo を含んでいない場合に、Wspiapi.h ヘッダーファイル内のコードに基づいて getnameinfo のバージョンがインラインで実装されるように、WspiapiGetNameInfo 関数が実装されます。このインラインコードは、getnameinfo 関数をネイティブにサポートしていない古い Windows プラットフォームで使用されます。IPv6 プロトコルは、Windows 2000 向け IPv6 Technology Preview がインストールされている場合に Windows 2000 でサポートされます。それ以外の場合、Windows XP より前のバージョンの Windows での getnameinfo のサポートは IPv4 名前解決の処理に限定されます。
GetNameInfoW 関数は getnameinfo の Unicode バージョンです。GetNameInfoW 関数は Windows XP SP2 の Ws2_32.dll に追加されました。GetNameInfoW 関数は、Windows XP SP2 より前のバージョンの Windows では使用できません。
Windows Phone 8: この関数は、Windows Phone 8 以降の Windows Phone ストアアプリでサポートされています。
Windows 8.1 および Windows Server 2012 R2: この関数は、Windows 8.1、Windows Server 2012 R2 以降の Windows ストアアプリでサポートされています。
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)
各言語での呼び出し定義
// WS2_32.dll
#include <windows.h>
INT getnameinfo(
const SOCKADDR* pSockaddr,
socklen_t SockaddrLength,
LPSTR pNodeBuffer, // optional
DWORD NodeBufferSize,
LPSTR pServiceBuffer, // optional
DWORD ServiceBufferSize,
INT Flags
);[DllImport("WS2_32.dll", SetLastError = true, ExactSpelling = true)]
static extern int getnameinfo(
IntPtr pSockaddr, // SOCKADDR*
int SockaddrLength, // socklen_t
[MarshalAs(UnmanagedType.LPStr)] System.Text.StringBuilder pNodeBuffer, // LPSTR optional, out
uint NodeBufferSize, // DWORD
[MarshalAs(UnmanagedType.LPStr)] System.Text.StringBuilder pServiceBuffer, // LPSTR optional, out
uint ServiceBufferSize, // DWORD
int Flags // INT
);<DllImport("WS2_32.dll", SetLastError:=True, ExactSpelling:=True)>
Public Shared Function getnameinfo(
pSockaddr As IntPtr, ' SOCKADDR*
SockaddrLength As Integer, ' socklen_t
<MarshalAs(UnmanagedType.LPStr)> pNodeBuffer As System.Text.StringBuilder, ' LPSTR optional, out
NodeBufferSize As UInteger, ' DWORD
<MarshalAs(UnmanagedType.LPStr)> pServiceBuffer As System.Text.StringBuilder, ' LPSTR optional, out
ServiceBufferSize As UInteger, ' DWORD
Flags As Integer ' INT
) As Integer
End Function' pSockaddr : SOCKADDR*
' SockaddrLength : socklen_t
' pNodeBuffer : LPSTR optional, out
' NodeBufferSize : DWORD
' pServiceBuffer : LPSTR optional, out
' ServiceBufferSize : DWORD
' Flags : INT
Declare PtrSafe Function getnameinfo Lib "ws2_32" ( _
ByVal pSockaddr As LongPtr, _
ByVal SockaddrLength As Long, _
ByVal pNodeBuffer As String, _
ByVal NodeBufferSize As Long, _
ByVal pServiceBuffer As String, _
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
getnameinfo = ctypes.windll.ws2_32.getnameinfo
getnameinfo.restype = ctypes.c_int
getnameinfo.argtypes = [
ctypes.c_void_p, # pSockaddr : SOCKADDR*
ctypes.c_int, # SockaddrLength : socklen_t
wintypes.LPSTR, # pNodeBuffer : LPSTR optional, out
wintypes.DWORD, # NodeBufferSize : DWORD
wintypes.LPSTR, # pServiceBuffer : LPSTR optional, out
wintypes.DWORD, # ServiceBufferSize : DWORD
ctypes.c_int, # Flags : INT
]
# GetLastError: use ctypes.GetLastError() (or ctypes.WinDLL(use_last_error=True))require 'fiddle'
require 'fiddle/import'
lib = Fiddle.dlopen('WS2_32.dll')
getnameinfo = Fiddle::Function.new(
lib['getnameinfo'],
[
Fiddle::TYPE_VOIDP, # pSockaddr : SOCKADDR*
Fiddle::TYPE_INT, # SockaddrLength : socklen_t
Fiddle::TYPE_VOIDP, # pNodeBuffer : LPSTR optional, out
-Fiddle::TYPE_INT, # NodeBufferSize : DWORD
Fiddle::TYPE_VOIDP, # pServiceBuffer : LPSTR optional, out
-Fiddle::TYPE_INT, # ServiceBufferSize : DWORD
Fiddle::TYPE_INT, # Flags : INT
],
Fiddle::TYPE_INT)#[link(name = "ws2_32")]
extern "system" {
fn getnameinfo(
pSockaddr: *const SOCKADDR, // SOCKADDR*
SockaddrLength: i32, // socklen_t
pNodeBuffer: *mut u8, // LPSTR optional, out
NodeBufferSize: u32, // DWORD
pServiceBuffer: *mut u8, // LPSTR optional, out
ServiceBufferSize: u32, // DWORD
Flags: i32 // INT
) -> i32;
}
// crates: windows-sys provides ready-made bindings for this API.$sig = @"
[DllImport("WS2_32.dll", SetLastError = true)]
public static extern int getnameinfo(IntPtr pSockaddr, int SockaddrLength, [MarshalAs(UnmanagedType.LPStr)] System.Text.StringBuilder pNodeBuffer, uint NodeBufferSize, [MarshalAs(UnmanagedType.LPStr)] System.Text.StringBuilder pServiceBuffer, uint ServiceBufferSize, int Flags);
"@
$api = Add-Type -MemberDefinition $sig -Name 'WS2_32_getnameinfo' -Namespace Win32 -PassThru
# $api::getnameinfo(pSockaddr, SockaddrLength, pNodeBuffer, NodeBufferSize, pServiceBuffer, ServiceBufferSize, Flags)#uselib "WS2_32.dll"
#func global getnameinfo "getnameinfo" sptr, sptr, sptr, sptr, sptr, sptr, sptr
; getnameinfo varptr(pSockaddr), SockaddrLength, varptr(pNodeBuffer), NodeBufferSize, varptr(pServiceBuffer), ServiceBufferSize, Flags ; 戻り値は stat
; pSockaddr : SOCKADDR* -> "sptr"
; SockaddrLength : socklen_t -> "sptr"
; pNodeBuffer : LPSTR optional, out -> "sptr"
; NodeBufferSize : DWORD -> "sptr"
; pServiceBuffer : LPSTR optional, out -> "sptr"
; ServiceBufferSize : DWORD -> "sptr"
; Flags : INT -> "sptr"
; ※HSP3.7は #func のため戻り値はシステム変数 stat に格納されます。#uselib "WS2_32.dll" #cfunc global getnameinfo "getnameinfo" var, int, var, int, var, int, int ; res = getnameinfo(pSockaddr, SockaddrLength, pNodeBuffer, NodeBufferSize, pServiceBuffer, ServiceBufferSize, Flags) ; pSockaddr : SOCKADDR* -> "var" ; SockaddrLength : socklen_t -> "int" ; pNodeBuffer : LPSTR optional, out -> "var" ; NodeBufferSize : DWORD -> "int" ; pServiceBuffer : LPSTR optional, out -> "var" ; ServiceBufferSize : DWORD -> "int" ; Flags : INT -> "int" ; ※出力/バッファ引数は var 方式(変数を直接渡す)。varptr 方式にも切替可。#uselib "WS2_32.dll" #cfunc global getnameinfo "getnameinfo" sptr, int, sptr, int, sptr, int, int ; res = getnameinfo(varptr(pSockaddr), SockaddrLength, varptr(pNodeBuffer), NodeBufferSize, varptr(pServiceBuffer), ServiceBufferSize, Flags) ; pSockaddr : SOCKADDR* -> "sptr" ; SockaddrLength : socklen_t -> "int" ; pNodeBuffer : LPSTR optional, out -> "sptr" ; NodeBufferSize : DWORD -> "int" ; pServiceBuffer : LPSTR optional, out -> "sptr" ; ServiceBufferSize : DWORD -> "int" ; Flags : INT -> "int" ; ※出力/バッファ引数はポインタ方式(token=sptr / 呼び出しは varptr(変数))。
; INT getnameinfo(SOCKADDR* pSockaddr, socklen_t SockaddrLength, LPSTR pNodeBuffer, DWORD NodeBufferSize, LPSTR pServiceBuffer, DWORD ServiceBufferSize, INT Flags) #uselib "WS2_32.dll" #cfunc global getnameinfo "getnameinfo" var, int, var, int, var, int, int ; res = getnameinfo(pSockaddr, SockaddrLength, pNodeBuffer, NodeBufferSize, pServiceBuffer, ServiceBufferSize, Flags) ; pSockaddr : SOCKADDR* -> "var" ; SockaddrLength : socklen_t -> "int" ; pNodeBuffer : LPSTR optional, out -> "var" ; NodeBufferSize : DWORD -> "int" ; pServiceBuffer : LPSTR optional, out -> "var" ; ServiceBufferSize : DWORD -> "int" ; Flags : INT -> "int" ; ※出力/バッファ引数は var 方式(変数を直接渡す)。varptr 方式にも切替可。; INT getnameinfo(SOCKADDR* pSockaddr, socklen_t SockaddrLength, LPSTR pNodeBuffer, DWORD NodeBufferSize, LPSTR pServiceBuffer, DWORD ServiceBufferSize, INT Flags) #uselib "WS2_32.dll" #cfunc global getnameinfo "getnameinfo" intptr, int, intptr, int, intptr, int, int ; res = getnameinfo(varptr(pSockaddr), SockaddrLength, varptr(pNodeBuffer), NodeBufferSize, varptr(pServiceBuffer), ServiceBufferSize, Flags) ; pSockaddr : SOCKADDR* -> "intptr" ; SockaddrLength : socklen_t -> "int" ; pNodeBuffer : LPSTR optional, out -> "intptr" ; NodeBufferSize : DWORD -> "int" ; pServiceBuffer : LPSTR optional, out -> "intptr" ; ServiceBufferSize : DWORD -> "int" ; Flags : INT -> "int" ; ※出力/バッファ引数はポインタ方式(token=intptr / 呼び出しは varptr(変数))。
import (
"golang.org/x/sys/windows"
"unsafe"
)
var (
ws2_32 = windows.NewLazySystemDLL("WS2_32.dll")
procgetnameinfo = ws2_32.NewProc("getnameinfo")
)
// pSockaddr (SOCKADDR*), SockaddrLength (socklen_t), pNodeBuffer (LPSTR optional, out), NodeBufferSize (DWORD), pServiceBuffer (LPSTR optional, out), ServiceBufferSize (DWORD), Flags (INT)
r1, _, err := procgetnameinfo.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 // INTfunction getnameinfo(
pSockaddr: Pointer; // SOCKADDR*
SockaddrLength: Integer; // socklen_t
pNodeBuffer: PAnsiChar; // LPSTR optional, out
NodeBufferSize: DWORD; // DWORD
pServiceBuffer: PAnsiChar; // LPSTR optional, out
ServiceBufferSize: DWORD; // DWORD
Flags: Integer // INT
): Integer; stdcall;
external 'WS2_32.dll' name 'getnameinfo';result := DllCall("WS2_32\getnameinfo"
, "Ptr", pSockaddr ; SOCKADDR*
, "Int", SockaddrLength ; socklen_t
, "Ptr", pNodeBuffer ; LPSTR optional, out
, "UInt", NodeBufferSize ; DWORD
, "Ptr", pServiceBuffer ; LPSTR optional, out
, "UInt", ServiceBufferSize ; DWORD
, "Int", Flags ; INT
, "Int") ; return: INT●getnameinfo(pSockaddr, SockaddrLength, pNodeBuffer, NodeBufferSize, pServiceBuffer, ServiceBufferSize, Flags) = DLL("WS2_32.dll", "int getnameinfo(void*, int, char*, dword, char*, dword, int)")
# 呼び出し: getnameinfo(pSockaddr, SockaddrLength, pNodeBuffer, NodeBufferSize, pServiceBuffer, ServiceBufferSize, Flags)
# pSockaddr : SOCKADDR* -> "void*"
# SockaddrLength : socklen_t -> "int"
# pNodeBuffer : LPSTR optional, out -> "char*"
# NodeBufferSize : DWORD -> "dword"
# pServiceBuffer : LPSTR 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 getnameinfo(
pSockaddr: [*c]SOCKADDR, // SOCKADDR*
SockaddrLength: i32, // socklen_t
pNodeBuffer: [*c]u8, // LPSTR optional, out
NodeBufferSize: u32, // DWORD
pServiceBuffer: [*c]u8, // LPSTR optional, out
ServiceBufferSize: u32, // DWORD
Flags: i32 // INT
) callconv(std.os.windows.WINAPI) i32;proc getnameinfo(
pSockaddr: ptr SOCKADDR, # SOCKADDR*
SockaddrLength: int32, # socklen_t
pNodeBuffer: ptr char, # LPSTR optional, out
NodeBufferSize: uint32, # DWORD
pServiceBuffer: ptr char, # LPSTR optional, out
ServiceBufferSize: uint32, # DWORD
Flags: int32 # INT
): int32 {.importc: "getnameinfo", stdcall, dynlib: "WS2_32.dll".}pragma(lib, "ws2_32");
extern(Windows)
int getnameinfo(
SOCKADDR* pSockaddr, // SOCKADDR*
int SockaddrLength, // socklen_t
char* pNodeBuffer, // LPSTR optional, out
uint NodeBufferSize, // DWORD
char* pServiceBuffer, // LPSTR optional, out
uint ServiceBufferSize, // DWORD
int Flags // INT
);ccall((:getnameinfo, "WS2_32.dll"), stdcall, Int32,
(Ptr{SOCKADDR}, Int32, Ptr{UInt8}, UInt32, Ptr{UInt8}, UInt32, Int32),
pSockaddr, SockaddrLength, pNodeBuffer, NodeBufferSize, pServiceBuffer, ServiceBufferSize, Flags)
# pSockaddr : SOCKADDR* -> Ptr{SOCKADDR}
# SockaddrLength : socklen_t -> Int32
# pNodeBuffer : LPSTR optional, out -> Ptr{UInt8}
# NodeBufferSize : DWORD -> UInt32
# pServiceBuffer : LPSTR optional, out -> Ptr{UInt8}
# ServiceBufferSize : DWORD -> UInt32
# Flags : INT -> Int32
# stdcall は 32bit のみ意味を持つ(x64 では無視)。local ffi = require("ffi")
ffi.cdef[[
int32_t getnameinfo(
void* pSockaddr,
int32_t SockaddrLength,
char* pNodeBuffer,
uint32_t NodeBufferSize,
char* pServiceBuffer,
uint32_t ServiceBufferSize,
int32_t Flags);
]]
local ws2_32 = ffi.load("ws2_32")
-- ws2_32.getnameinfo(pSockaddr, SockaddrLength, pNodeBuffer, NodeBufferSize, pServiceBuffer, ServiceBufferSize, Flags)
-- pSockaddr : SOCKADDR*
-- SockaddrLength : socklen_t
-- pNodeBuffer : LPSTR optional, out
-- NodeBufferSize : DWORD
-- pServiceBuffer : LPSTR optional, out
-- ServiceBufferSize : DWORD
-- Flags : INT
-- 構造体/GUIDへのポインタは cdef が通るよう void* で表記(実型は各引数コメント参照)。値渡し構造体・enum は対応する typedef を cdef に追加すること。const koffi = require('koffi');
const lib = koffi.load('WS2_32.dll');
const getnameinfo = lib.func('__stdcall', 'getnameinfo', 'int32_t', ['void *', 'int32_t', 'char *', 'uint32_t', 'char *', 'uint32_t', 'int32_t']);
// getnameinfo(pSockaddr, SockaddrLength, pNodeBuffer, NodeBufferSize, pServiceBuffer, ServiceBufferSize, Flags)
// pSockaddr : SOCKADDR* -> 'void *'
// SockaddrLength : socklen_t -> 'int32_t'
// pNodeBuffer : LPSTR optional, out -> 'char *'
// NodeBufferSize : DWORD -> 'uint32_t'
// pServiceBuffer : LPSTR optional, out -> 'char *'
// ServiceBufferSize : DWORD -> 'uint32_t'
// Flags : INT -> 'int32_t'
// 出力ポインタは koffi.out(...) で包む。構造体は koffi.struct で定義。const lib = Deno.dlopen("WS2_32.dll", {
getnameinfo: { parameters: ["pointer", "i32", "buffer", "u32", "buffer", "u32", "i32"], result: "i32" },
});
// lib.symbols.getnameinfo(pSockaddr, SockaddrLength, pNodeBuffer, NodeBufferSize, pServiceBuffer, ServiceBufferSize, Flags)
// pSockaddr : SOCKADDR* -> "pointer"
// SockaddrLength : socklen_t -> "i32"
// pNodeBuffer : LPSTR optional, out -> "buffer"
// NodeBufferSize : DWORD -> "u32"
// pServiceBuffer : LPSTR optional, out -> "buffer"
// ServiceBufferSize : DWORD -> "u32"
// Flags : INT -> "i32"
// 文字列引数は "buffer"(NUL 終端のバイト列を Uint8Array で渡す)。
// 値渡し構造体は { struct: [ ...field types... ] } を使用。<?php
$ffi = FFI::cdef(<<<C
int32_t getnameinfo(
void* pSockaddr,
int32_t SockaddrLength,
char* pNodeBuffer,
uint32_t NodeBufferSize,
char* pServiceBuffer,
uint32_t ServiceBufferSize,
int32_t Flags);
C, "WS2_32.dll");
// $ffi->getnameinfo(pSockaddr, SockaddrLength, pNodeBuffer, NodeBufferSize, pServiceBuffer, ServiceBufferSize, Flags);
// pSockaddr : SOCKADDR*
// SockaddrLength : socklen_t
// pNodeBuffer : LPSTR optional, out
// NodeBufferSize : DWORD
// pServiceBuffer : LPSTR 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 getnameinfo(
Pointer pSockaddr, // SOCKADDR*
int SockaddrLength, // socklen_t
byte[] pNodeBuffer, // LPSTR optional, out
int NodeBufferSize, // DWORD
byte[] pServiceBuffer, // LPSTR optional, out
int ServiceBufferSize, // DWORD
int Flags // INT
);
}@[Link("ws2_32")]
lib LibWS2_32
fun getnameinfo = getnameinfo(
pSockaddr : SOCKADDR*, # SOCKADDR*
SockaddrLength : Int32, # socklen_t
pNodeBuffer : UInt8*, # LPSTR optional, out
NodeBufferSize : UInt32, # DWORD
pServiceBuffer : UInt8*, # LPSTR 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 getnameinfoNative = Int32 Function(Pointer<Void>, Int32, Pointer<Utf8>, Uint32, Pointer<Utf8>, Uint32, Int32);
typedef getnameinfoDart = int Function(Pointer<Void>, int, Pointer<Utf8>, int, Pointer<Utf8>, int, int);
final getnameinfo = DynamicLibrary.open('WS2_32.dll')
.lookupFunction<getnameinfoNative, getnameinfoDart>('getnameinfo');
// pSockaddr : SOCKADDR* -> Pointer<Void>
// SockaddrLength : socklen_t -> Int32
// pNodeBuffer : LPSTR optional, out -> Pointer<Utf8>
// NodeBufferSize : DWORD -> Uint32
// pServiceBuffer : LPSTR optional, out -> Pointer<Utf8>
// ServiceBufferSize : DWORD -> Uint32
// Flags : INT -> Int32
// 文字列は package:ffi の "...".toNativeUtf16()/toNativeUtf8() で変換。{$mode objfpc}{$H+}
function getnameinfo(
pSockaddr: Pointer; // SOCKADDR*
SockaddrLength: Integer; // socklen_t
pNodeBuffer: PAnsiChar; // LPSTR optional, out
NodeBufferSize: DWORD; // DWORD
pServiceBuffer: PAnsiChar; // LPSTR optional, out
ServiceBufferSize: DWORD; // DWORD
Flags: Integer // INT
): Integer; stdcall;
external 'WS2_32.dll' name 'getnameinfo';import Foreign
import Foreign.C.Types
import Foreign.C.String
foreign import stdcall safe "getnameinfo"
c_getnameinfo :: Ptr () -> Int32 -> CString -> Word32 -> CString -> Word32 -> Int32 -> IO Int32
-- pSockaddr : SOCKADDR* -> Ptr ()
-- SockaddrLength : socklen_t -> Int32
-- pNodeBuffer : LPSTR optional, out -> CString
-- NodeBufferSize : DWORD -> Word32
-- pServiceBuffer : LPSTR optional, out -> CString
-- ServiceBufferSize : DWORD -> Word32
-- Flags : INT -> Int32
-- 要 GHC(Windows)。stdcall は x64 では ccall として扱われる。ブロックする API は safe 呼び出し推奨。open Ctypes
open Foreign
let getnameinfo =
foreign "getnameinfo"
((ptr void) @-> int32_t @-> string @-> uint32_t @-> string @-> uint32_t @-> int32_t @-> returning int32_t)
(* pSockaddr : SOCKADDR* -> (ptr void) *)
(* SockaddrLength : socklen_t -> int32_t *)
(* pNodeBuffer : LPSTR optional, out -> string *)
(* NodeBufferSize : DWORD -> uint32_t *)
(* pServiceBuffer : LPSTR optional, out -> string *)
(* 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 ("getnameinfo" getnameinfo :convention :stdcall) :int32
(p-sockaddr :pointer) ; SOCKADDR*
(sockaddr-length :int32) ; socklen_t
(p-node-buffer :pointer) ; LPSTR optional, out
(node-buffer-size :uint32) ; DWORD
(p-service-buffer :pointer) ; LPSTR 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 $getnameinfo = Win32::API::More->new('WS2_32',
'int getnameinfo(LPVOID pSockaddr, int SockaddrLength, LPSTR pNodeBuffer, DWORD NodeBufferSize, LPSTR pServiceBuffer, DWORD ServiceBufferSize, int Flags)');
# my $ret = $getnameinfo->Call($pSockaddr, $SockaddrLength, $pNodeBuffer, $NodeBufferSize, $pServiceBuffer, $ServiceBufferSize, $Flags);
# pSockaddr : SOCKADDR* -> LPVOID
# SockaddrLength : socklen_t -> int
# pNodeBuffer : LPSTR optional, out -> LPSTR
# NodeBufferSize : DWORD -> DWORD
# pServiceBuffer : LPSTR optional, out -> LPSTR
# ServiceBufferSize : DWORD -> DWORD
# Flags : INT -> int
# 値渡し構造体は pack() した文字列、または Win32::API::Struct を使用。関連項目
- f GetNameInfoW — ソケットアドレスからホスト名とサービス名をUnicodeで取得する。
- f WSAGetLastError — 直前のソケット操作のエラーコードを取得する。
- f getaddrinfo — ホスト名やサービス名からアドレス情報を解決する。