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

WSASetServiceA

関数
サービスインスタンスの登録や登録解除を行う。
DLLWS2_32.dll文字セットANSI (-A)呼出規約winapiSetLastErrorあり対応OSWindows 8.1 以降

シグネチャ

// WS2_32.dll  (ANSI / -A)
#include <windows.h>

INT WSASetServiceA(
    WSAQUERYSETA* lpqsRegInfo,
    WSAESETSERVICEOP essoperation,
    DWORD dwControlFlags
);

パラメーター

名前方向説明
lpqsRegInfoWSAQUERYSETA*in登録または登録解除を行うサービス情報へのポインター。
essoperationWSAESETSERVICEOPin

要求する操作を決定する値。このパラメーターには、Winsock2.h ヘッダーファイルで定義されている WSAESETSERVICEOP 列挙型の値のいずれかを指定できます。

意味
RNRSERVICE_REGISTER
サービスを登録します。SAP の場合、これは定期的なブロードキャストの送信を意味します。DNS 名前空間に対しては何も行いません (NOP)。永続的なデータストアの場合、これはアドレス情報の更新を意味します。
RNRSERVICE_DEREGISTER
サービスをレジストリから削除します。SAP の場合、これは定期的なブロードキャストの送信を停止することを意味します。DNS 名前空間に対しては何も行いません (NOP)。永続的なデータストアの場合、これはアドレス情報の削除を意味します。
RNRSERVICE_DELETE
動的名前空間および永続的空間からサービスを削除します。複数の CSADDR_INFO 構造体で表されるサービス (SERVICE_MULTIPLE フラグを使用) の場合、指定されたアドレスのみが削除されます。このアドレスは、サービス登録時に指定された対応する CSADDR_INFO 構造体と正確に一致する必要があります。
dwControlFlagsDWORDin

WSASetService 関数が実行する操作をさらに制御するサービスインストールフラグの値。このパラメーターに指定可能な値は、Winsock2.h ヘッダーファイルで定義されています。

フラグ 意味
SERVICE_MULTIPLE
操作の範囲を制御します。このフラグが設定されていない場合、サービスアドレスはグループとして管理されます。レジストリへの登録またはレジストリからの削除は、指定されたアドレスセットを追加する前に、既存のすべてのアドレスを無効化します。このフラグが設定されている場合、操作は指定されたアドレスセットに対してのみ実行されます。登録は既存のアドレスを無効化せず、レジストリからの削除は指定されたアドレスセットのみを無効化します。

戻り値の型: INT

公式ドキュメント

WSASetService 関数は、1 つ以上の名前空間内にサービスインスタンスをレジストリに登録するか、レジストリから削除します。(ANSI)

戻り値

WSASetService の戻り値は、操作が成功した場合は 0 です。それ以外の場合は SOCKET_ERROR が返され、 WSAGetLastError を呼び出すことで具体的なエラー番号を取得できます。

エラーコード 意味
WSAEACCES
呼び出し元のルーチンに、サービスをインストールするための十分な権限がありません。
WSAEINVAL
1 つ以上の必須パラメーターが無効であるか、不足していました。
WSANOTINITIALISED
Ws2_32.dll が初期化されていません。アプリケーションは、Windows Sockets 関数を呼び出す前に、まず WSAStartup を呼び出す必要があります。
WSA_NOT_ENOUGH_MEMORY
操作を実行するためのメモリが不足していました。

解説(Remarks)

WSASetService 関数を使用すると、特定の名前空間プロバイダー、特定の名前空間に関連付けられたすべてのプロバイダー、またはすべての名前空間にまたがるすべてのプロバイダーに対して操作を行えます。

essOperationdwControlFlags に指定可能な値を組み合わせることで、次の表に示すように WSASetService 関数の動作を制御します。

操作 フラグ サービスが既に存在する場合 サービスが存在しない場合
RNRSERVICE_REGISTER なし オブジェクトを上書きします。指定されたアドレスのみを使用します。オブジェクトは REGISTERED になります。 新しいオブジェクトを作成します。指定されたアドレスのみを使用します。オブジェクトは REGISTERED になります。
RNRSERVICE_REGISTER SERVICE_MULTIPLE オブジェクトを更新します。既存のセットに新しいアドレスを追加します。オブジェクトは REGISTERED になります。 新しいオブジェクトを作成します。指定されたすべてのアドレスを使用します。オブジェクトは REGISTERED になります。
RNRSERVICE_DEREGISTER なし すべてのアドレスを削除しますが、名前空間からオブジェクトは削除しません。オブジェクトはレジストリから削除されます。 WSASERVICE_NOT_FOUND
RNRSERVICE_DEREGISTER SERVICE_MULTIPLE オブジェクトを更新します。指定されたアドレスのみを削除します。アドレスが 1 つも残っていない場合にのみ、オブジェクトを DEREGISTERED としてマークします。名前空間からオブジェクトは削除しません。 WSASERVICE_NOT_FOUND
RNRSERVICE_DELETE なし 名前空間からオブジェクトを削除します。 WSASERVICE_NOT_FOUND
RNRSERVICE_DELETE SERVICE_MULTIPLE 指定されたアドレスのみを削除します。アドレスが 1 つも残っていない場合にのみ、名前空間からオブジェクトを削除します。 WSASERVICE_NOT_FOUND

Active Directory Services などのディレクトリへのサービスの公開は、アクセス制御リスト (ACL) に基づいて制限されます。詳細については、Security Issues for Service Publication を参照してください。

dwControlFlags パラメーターに SERVICE_MULTIPLE が設定されている場合、アプリケーションは自身のアドレスを個別に管理できます。これは、アプリケーションがプロトコルを個別に管理したい場合や、サービスが複数のコンピューター上に存在する場合に役立ちます。たとえば、サービスが複数のプロトコルを使用している場合に、ある待ち受けソケットが異常終了しても他のソケットは稼働し続けることがあります。この場合、サービスは他のアドレスに影響を与えることなく、異常終了したアドレスをレジストリから削除できます。

dwControlFlags パラメーターに SERVICE_MULTIPLE が設定されている場合、アプリケーションは古いアドレスがオブジェクト内に残らないようにする必要があります。これは、アプリケーションが DEREGISTER 要求を発行せずに異常終了した場合に発生する可能性があります。サービスが登録を行う際は、自身のアドレスを保存しておく必要があります。次回の起動時に、サービスは新しいアドレスを登録する前に、これらの古い不要なアドレスをレジストリから明示的に削除する必要があります。

注意 ANSI 文字列を使用する場合、この関数が返った後、lpqsRegInfo 内の WSAQUERYSET データに結果が含まれない可能性があります。これは、このメソッドの ANSI 版である WSASetServiceA が、WSAQUERYSET 内の ANSI データを内部的に Unicode に変換するものの、結果を ANSI に変換し直さないためです。これは主に、レコードを一意に識別するために使用される「サービスレコードハンドル」を返すトランスポートに影響します。この問題を回避するには、アプリケーションはこの関数を呼び出す際に WSAQUERYSET 内で Unicode 文字列データを使用する必要があります。

サービスプロパティ

サービスプロパティのデータが WSAQUERYSET 構造体でどのように表現されるかを、次の表に示します。(省略可能) と記載されているフィールドには null ポインターを指定できます。
WSAQUERYSET のメンバー サービスプロパティの説明
dwSize sizeof (WSAQUERYSET) を設定する必要があります。これはバージョン管理の仕組みです。
dwOutputFlags 該当しないため無視されます。
lpszServiceInstanceName 参照される文字列にはサービスインスタンス名が含まれます。
lpServiceClassId このサービスクラスに対応する GUID。
lpVersion (省略可能) サービスインスタンスのバージョン番号を指定します。
lpszComment (省略可能) 任意のコメント文字列。
dwNameSpace 後続の表を参照してください。
lpNSProviderId 後続の表を参照してください。
lpszContext (省略可能) 階層的な名前空間におけるクエリの開始点を指定します。
dwNumberOfProtocols 無視されます。
lpafpProtocols 無視されます。
lpszQueryString 無視されます。
dwNumberOfCsAddrs lpcsaBuffer が参照する CSADDR_INFO 構造体の配列内の要素数。
lpcsaBuffer サービスが待ち受けているアドレスを含む CSADDR_INFO 構造体の配列へのポインター。
lpBlob (省略可能) これはプロバイダー固有のエンティティへのポインターです。

次に示すように、dwNameSpace メンバーと lpNSProviderId メンバーの組み合わせによって、この関数の影響を受ける名前空間プロバイダーが決まります。

dwNameSpace lpNSProviderId 影響の範囲
無視される 非 null 指定された名前空間プロバイダー。
有効な名前空間識別子 Null 指定された名前空間をサポートするすべての名前空間プロバイダー。
NS_ALL Null すべての名前空間プロバイダー。

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

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

メモ

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

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

各言語での呼び出し定義

// WS2_32.dll  (ANSI / -A)
#include <windows.h>

INT WSASetServiceA(
    WSAQUERYSETA* lpqsRegInfo,
    WSAESETSERVICEOP essoperation,
    DWORD dwControlFlags
);
[DllImport("WS2_32.dll", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
static extern int WSASetServiceA(
    IntPtr lpqsRegInfo,   // WSAQUERYSETA*
    int essoperation,   // WSAESETSERVICEOP
    uint dwControlFlags   // DWORD
);
<DllImport("WS2_32.dll", CharSet:=CharSet.Ansi, SetLastError:=True, ExactSpelling:=True)>
Public Shared Function WSASetServiceA(
    lpqsRegInfo As IntPtr,   ' WSAQUERYSETA*
    essoperation As Integer,   ' WSAESETSERVICEOP
    dwControlFlags As UInteger   ' DWORD
) As Integer
End Function
' lpqsRegInfo : WSAQUERYSETA*
' essoperation : WSAESETSERVICEOP
' dwControlFlags : DWORD
Declare PtrSafe Function WSASetServiceA Lib "ws2_32" ( _
    ByVal lpqsRegInfo As LongPtr, _
    ByVal essoperation As Long, _
    ByVal dwControlFlags As Long) As Long
' VBA7前提(PtrSafe)。32bit Office では LongPtr→Long。Integer=16bit / Long=32bit / LongLong=64bit。
import ctypes
from ctypes import wintypes

WSASetServiceA = ctypes.windll.ws2_32.WSASetServiceA
WSASetServiceA.restype = ctypes.c_int
WSASetServiceA.argtypes = [
    ctypes.c_void_p,  # lpqsRegInfo : WSAQUERYSETA*
    ctypes.c_int,  # essoperation : WSAESETSERVICEOP
    wintypes.DWORD,  # dwControlFlags : DWORD
]
# GetLastError: use ctypes.GetLastError() (or ctypes.WinDLL(use_last_error=True))
require 'fiddle'
require 'fiddle/import'

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

var (
	ws2_32 = windows.NewLazySystemDLL("WS2_32.dll")
	procWSASetServiceA = ws2_32.NewProc("WSASetServiceA")
)

// lpqsRegInfo (WSAQUERYSETA*), essoperation (WSAESETSERVICEOP), dwControlFlags (DWORD)
r1, _, err := procWSASetServiceA.Call(
	uintptr(lpqsRegInfo),
	uintptr(essoperation),
	uintptr(dwControlFlags),
)
_ = err  // syscall.Errno (valid when the call sets last-error)
_ = r1   // INT
function WSASetServiceA(
  lpqsRegInfo: Pointer;   // WSAQUERYSETA*
  essoperation: Integer;   // WSAESETSERVICEOP
  dwControlFlags: DWORD   // DWORD
): Integer; stdcall;
  external 'WS2_32.dll' name 'WSASetServiceA';
result := DllCall("WS2_32\WSASetServiceA"
    , "Ptr", lpqsRegInfo   ; WSAQUERYSETA*
    , "Int", essoperation   ; WSAESETSERVICEOP
    , "UInt", dwControlFlags   ; DWORD
    , "Int")   ; return: INT
●WSASetServiceA(lpqsRegInfo, essoperation, dwControlFlags) = DLL("WS2_32.dll", "int WSASetServiceA(void*, int, dword)")
# 呼び出し: WSASetServiceA(lpqsRegInfo, essoperation, dwControlFlags)
# lpqsRegInfo : WSAQUERYSETA* -> "void*"
# essoperation : WSAESETSERVICEOP -> "int"
# dwControlFlags : DWORD -> "dword"
# なでしこ1は32bit・ANSI(Shift_JIS)。文字列=char*(ANSI)、ポインタ/ハンドル=void*(4byte)。
const std = @import("std");

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

typedef WSASetServiceANative = Int32 Function(Pointer<Void>, Int32, Uint32);
typedef WSASetServiceADart = int Function(Pointer<Void>, int, int);
final WSASetServiceA = DynamicLibrary.open('WS2_32.dll')
    .lookupFunction<WSASetServiceANative, WSASetServiceADart>('WSASetServiceA');
// lpqsRegInfo : WSAQUERYSETA* -> Pointer<Void>
// essoperation : WSAESETSERVICEOP -> Int32
// dwControlFlags : DWORD -> Uint32
// 文字列は package:ffi の "...".toNativeUtf16()/toNativeUtf8() で変換。
{$mode objfpc}{$H+}
function WSASetServiceA(
  lpqsRegInfo: Pointer;   // WSAQUERYSETA*
  essoperation: Integer;   // WSAESETSERVICEOP
  dwControlFlags: DWORD   // DWORD
): Integer; stdcall;
  external 'WS2_32.dll' name 'WSASetServiceA';
import Foreign
import Foreign.C.Types
import Foreign.C.String

foreign import stdcall safe "WSASetServiceA"
  c_WSASetServiceA :: Ptr () -> Int32 -> Word32 -> IO Int32
-- lpqsRegInfo : WSAQUERYSETA* -> Ptr ()
-- essoperation : WSAESETSERVICEOP -> Int32
-- dwControlFlags : DWORD -> Word32
-- 要 GHC(Windows)。stdcall は x64 では ccall として扱われる。ブロックする API は safe 呼び出し推奨。
open Ctypes
open Foreign

let wsasetservicea =
  foreign "WSASetServiceA"
    ((ptr void) @-> int32_t @-> uint32_t @-> returning int32_t)
(* lpqsRegInfo : WSAQUERYSETA* -> (ptr void) *)
(* essoperation : WSAESETSERVICEOP -> int32_t *)
(* dwControlFlags : DWORD -> uint32_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 ("WSASetServiceA" wsaset-service-a :convention :stdcall) :int32
  (lpqs-reg-info :pointer)   ; WSAQUERYSETA*
  (essoperation :int32)   ; WSAESETSERVICEOP
  (dw-control-flags :uint32))   ; DWORD
; isize/usize(INT_PTR/SIZE_T)は x64 前提で :int64/:uint64。x86 では :int32/:uint32。
use Win32::API;
my $WSASetServiceA = Win32::API::More->new('WS2_32',
    'int WSASetServiceA(LPVOID lpqsRegInfo, int essoperation, DWORD dwControlFlags)');
# my $ret = $WSASetServiceA->Call($lpqsRegInfo, $essoperation, $dwControlFlags);
# lpqsRegInfo : WSAQUERYSETA* -> LPVOID
# essoperation : WSAESETSERVICEOP -> int
# dwControlFlags : DWORD -> DWORD
# 値渡し構造体は pack() した文字列、または Win32::API::Struct を使用。

関連項目

文字セット違い
公式の関連項目
使用する型