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

setsockopt

関数
ソケットオプションの値を設定する。
DLLWS2_32.dll呼出規約winapiSetLastErrorあり対応OSWindows 8.1 以降

シグネチャ

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

INT setsockopt(
    SOCKET s,
    INT level,
    INT optname,
    LPCSTR optval,   // optional
    INT optlen
);

パラメーター

名前方向説明
sSOCKETinソケットを識別するディスクリプタです。
levelINTinオプションが定義されているレベルです (例: SOL_SOCKET)。
optnameINTin値を設定する対象のソケットオプションです (例: SO_BROADCAST)。optname パラメータには、指定した level 内で定義されているソケットオプションを指定する必要があります。そうでない場合の動作は未定義です。
optvalLPCSTRinoptional要求するオプションの値を格納したバッファへのポインタです。
optlenINTinoptval パラメータが指すバッファのサイズ (バイト単位) です。

戻り値の型: INT

公式ドキュメント

setsockopt 関数 (winsock.h) は、ソケットオプションを設定します。

戻り値

エラーが発生しなかった場合、 setsockopt はゼロを返します。それ以外の場合は SOCKET_ERROR が返され、 WSAGetLastError を呼び出すことで具体的なエラーコードを取得できます。

エラーコード 意味
WSANOTINITIALISED
この関数を使用する前に、 WSAStartup の呼び出しが成功している必要があります。
WSAENETDOWN
ネットワークサブシステムに障害が発生しました。
WSAEFAULT
optval パラメータが指すバッファがプロセスのアドレス空間の有効な部分にないか、optlen パラメータが小さすぎます。
WSAEINPROGRESS
ブロッキングを行う Windows Sockets 1.1 の呼び出しが進行中であるか、サービスプロバイダがコールバック関数をまだ処理しています。
WSAEINVAL
level パラメータが無効であるか、optval パラメータが指すバッファ内の情報が無効です。
WSAENETRESET
SO_KEEPALIVE が設定されている状態で、接続がタイムアウトしました。
WSAENOPROTOOPT
指定したプロバイダまたはソケットでは、このオプションは不明であるかサポートされていません (SO_GROUP_PRIORITY の制限を参照してください)。
WSAENOTCONN
SO_KEEPALIVE が設定されている状態で、接続がリセットされました。
WSAENOTSOCK
ディスクリプタがソケットではありません。

解説(Remarks)

setsockopt 関数は、任意の型・任意の状態のソケットに関連付けられたソケットオプションの現在の値を設定します。オプションは複数のプロトコルレベルに存在し得ますが、常に最上位のソケットレベルにも存在します。オプションは、緊急データ (例: OOB データ) を通常のデータストリーム内で受信するかどうかや、ブロードキャストメッセージをソケット上で送信できるかどうかなど、ソケットの動作に影響します。

注意 setsockopt 関数を bind 関数より前に呼び出した場合、TCP/IP オプションは bind が行われるまで TCP/IP によってチェックされません。この場合、 setsockopt 関数の呼び出しは常に成功しますが、先行する setsockopt 呼び出しが失敗していると、それが原因で bind 関数の呼び出しが失敗することがあります。
注意 ソケットを開き、 setsockopt 呼び出しを行った後に sendto 呼び出しを行うと、Windows Sockets は暗黙的に bind 関数の呼び出しを実行します。
ソケットオプションには 2 種類あります。機能や動作を有効/無効にするブール型オプションと、整数値または構造体を必要とするオプションです。ブール型オプションを有効にするには、optval パラメータがゼロ以外の整数を指すようにします。オプションを無効にするには、optval がゼロに等しい整数を指すようにします。ブール型オプションの場合、optlen パラメータは sizeof(int) に等しくする必要があります。その他のオプションでは、optval はオプションに設定したい値を含む整数または構造体を指し、optlen はその整数または構造体の長さになります。

以下の表は、setsockopt 関数でサポートされる一般的なオプションの一部を示しています。Type 列は optval パラメータが指すデータの型を示します。Description 列はソケットオプションに関する基本的な情報を示します。ソケットオプションのより完全な一覧やより詳細な情報 (既定値など) については、Socket Options 以下の詳細トピックを参照してください。

level = SOL_SOCKET

Value Type Description
SO_BROADCAST BOOL ブロードキャストデータを送信するようにソケットを構成します。
SO_CONDITIONAL_ACCEPT BOOL 受信接続を、プロトコルスタックではなくアプリケーションが受け入れるか拒否するかを決定できるようにします。
SO_DEBUG BOOL デバッグ出力を有効にします。現在、Microsoft のプロバイダはデバッグ情報を出力しません。
SO_DONTLINGER BOOL 未送信データの送信を待って close をブロックしないようにします。このオプションの設定は、SO_LINGERl_onoff をゼロに設定して設定するのと同等です。
SO_DONTROUTE BOOL 送信データを、ソケットがバインドされているインターフェイス上で送信し、他のインターフェイス経由でルーティングしないかどうかを設定します。このオプションは ATM ソケットではサポートされません (エラーになります)。
SO_GROUP_PRIORITY int 予約済みです。
SO_KEEPALIVE BOOL ソケット接続に対する keep-alive パケットの送信を有効にします。ATM ソケットではサポートされません (エラーになります)。
SO_LINGER LINGER 未送信データが存在する場合、close 時に待機 (linger) します。
SO_OOBINLINE BOOL 帯域外 (out-of-bound) データを通常のデータと同じ流れの中で返すことを示します。このオプションは、帯域外データをサポートするコネクション指向プロトコルでのみ有効です。このトピックの説明については、 Protocol Independent Out-Of-band Data を参照してください。
SO_RCVBUF int 受信用にソケットごとに予約されるバッファ領域の合計を指定します。
SO_REUSEADDR BOOL すでに使用中のアドレスにソケットをバインドできるようにします。詳細については、 bind を参照してください。ATM ソケットには適用されません。
SO_EXCLUSIVEADDRUSE BOOL ソケットを排他アクセス用にバインドできるようにします。管理者権限は必要ありません。
SO_RCVTIMEO DWORD ブロッキングを行う受信呼び出しのタイムアウトをミリ秒単位で設定します。
SO_SNDBUF int 送信用にソケットごとに予約されるバッファ領域の合計を指定します。
SO_SNDTIMEO DWORD ブロッキングを行う送信呼び出しのタイムアウト (ミリ秒単位) です。
SO_UPDATE_ACCEPT_CONTEXT UINT_PTR 受け入れ側のソケットを、リッスン側のソケットのコンテキストで更新します。
PVD_CONFIG Service Provider Dependent このオブジェクトは、ソケット s に関連付けられたサービスプロバイダの構成情報を格納します。このデータ構造体の正確な形式は、サービスプロバイダ固有です。

level = SOL_SOCKET のソケットオプションに関するより完全で詳細な情報については、SOL_SOCKET Socket Options を参照してください。

level = IPPROTO_TCP

IPPROTO_TCP socket optionsTCP_NODELAY を参照してください。また、level = IPPROTO_TCP のソケットオプションに関するより完全で詳細な情報については、同じトピックを参照してください。

level = NSPROTO_IPX

Value Type Description
IPX_PTYPE int IPX パケットタイプを設定します。
IPX_FILTERPTYPE int 受信フィルタのパケットタイプを設定します。
IPX_STOPFILTERPTYPE int IPX_FILTERTYPE で設定したフィルタタイプによるフィルタリングを停止します。
IPX_DSTYPE int 送信する各パケットの SPX ヘッダー内のデータストリームフィールドの値を設定します。
IPX_EXTENDED_ADDRESS BOOL 拡張アドレッシングを有効にするかどうかを設定します。
IPX_RECVHDR BOOL すべての受信ヘッダーでプロトコルヘッダーを上位に渡すかどうかを設定します。
IPX_RECEIVE_BROADCAST BOOL ソケット上でブロードキャストパケットが発生する可能性が高いことを示します。既定では TRUE に設定されています。ブロードキャストを使用しないアプリケーションは、システムパフォーマンスを向上させるためにこれを FALSE に設定してください。
IPX_IMMEDIATESPXACK BOOL SPX 接続が ACK を送信する前に遅延しないように指示します。双方向のトラフィックがないアプリケーションは、パフォーマンスを向上させるためにこれを TRUE に設定してください。

level = NSPROTO_IPX のソケットオプションに関するより完全で詳細な情報については、NSPROTO_IPX Socket Options を参照してください。

setsockopt でサポートされない BSD オプションを次の表に示します。

Value Type Description
SO_ACCEPTCONN BOOL ソケットがリッスンモードであるかどうかを返します。このオプションはコネクション指向プロトコルでのみ有効です。このソケットオプションは設定用にはサポートされていません。
SO_RCVLOWAT int 下位互換性のために含まれている BSD UNIX 由来のソケットオプションです。このオプションは、ソケットの入力操作で処理する最小バイト数を設定します。
SO_SNDLOWAT int 下位互換性のために含まれている BSD UNIX 由来のソケットオプションです。このオプションは、ソケットの出力操作で処理する最小バイト数を設定します。
SO_TYPE int 指定したソケットのソケットタイプ (例: SOCK_STREAM または SOCK_DGRAM) を返します。このソケットオプションはソケットタイプの設定用にはサポートされていません。
注意 setsockopt のようなブロッキングを行う Winsock 呼び出しを発行する場合、呼び出しが完了する前に Winsock がネットワークイベントを待つ必要が生じることがあります。この状況で Winsock はアラータブルな待機を実行し、これは同一スレッド上でスケジュールされた非同期プロシージャ呼び出し (APC) によって中断される可能性があります。同一スレッド上で進行中のブロッキング Winsock 呼び出しを中断した APC 内で別のブロッキング Winsock 呼び出しを発行すると、未定義の動作につながるため、Winsock クライアントは決してこれを試みてはなりません。

Example Code

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

#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif

#include <winsock2.h>
#include <Ws2tcpip.h>
#include <stdio.h>

// Link with ws2_32.lib
#pragma comment(lib, "Ws2_32.lib")

int main()
{

    //---------------------------------------
    // Declare variables
    WSADATA wsaData;

    SOCKET ListenSocket;
    sockaddr_in service;

    int iResult = 0;

    BOOL bOptVal = FALSE;
    int bOptLen = sizeof (BOOL);

    int iOptVal = 0;
    int iOptLen = sizeof (int);

    //---------------------------------------
    // Initialize Winsock
    iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
    if (iResult != NO_ERROR) {
        wprintf(L"Error at WSAStartup()\n");
        return 1;
    }
    //---------------------------------------
    // Create a listening socket
    ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (ListenSocket == INVALID_SOCKET) {
        wprintf(L"socket function failed with error: %u\n", WSAGetLastError());
        WSACleanup();
        return 1;
    }
    //---------------------------------------
    // Bind the socket to the local IP address
    // and port 27015
    hostent *thisHost;
    char *ip;
    u_short port;
    port = 27015;
    thisHost = gethostbyname("");
    ip = inet_ntoa(*(struct in_addr *) *thisHost->h_addr_list);

    service.sin_family = AF_INET;
    service.sin_addr.s_addr = inet_addr(ip);
    service.sin_port = htons(port);

    iResult = bind(ListenSocket, (SOCKADDR *) & service, sizeof (service));
    if (iResult == SOCKET_ERROR) {
        wprintf(L"bind failed with error %u\n", WSAGetLastError());
        closesocket(ListenSocket);
        WSACleanup();
        return 1;
    }
    //---------------------------------------
    // Initialize variables and call setsockopt. 
    // The SO_KEEPALIVE parameter is a socket option 
    // that makes the socket send keepalive messages
    // on the session. The SO_KEEPALIVE socket option
    // requires a boolean value to be passed to the
    // setsockopt function. If TRUE, the socket is
    // configured to send keepalive messages, if FALSE
    // the socket configured to NOT send keepalive messages.
    // This section of code tests the setsockopt function
    // by checking the status of SO_KEEPALIVE on the socket
    // using the getsockopt function.

    bOptVal = TRUE;

    iResult = getsockopt(ListenSocket, SOL_SOCKET, SO_KEEPALIVE, (char *) &iOptVal, &iOptLen);
    if (iResult == SOCKET_ERROR) {
        wprintf(L"getsockopt for SO_KEEPALIVE failed with error: %u\n", WSAGetLastError());
    } else
        wprintf(L"SO_KEEPALIVE Value: %ld\n", iOptVal);

    iResult = setsockopt(ListenSocket, SOL_SOCKET, SO_KEEPALIVE, (char *) &bOptVal, bOptLen);
    if (iResult == SOCKET_ERROR) {
        wprintf(L"setsockopt for SO_KEEPALIVE failed with error: %u\n", WSAGetLastError());
    } else
        wprintf(L"Set SO_KEEPALIVE: ON\n");

    iResult = getsockopt(ListenSocket, SOL_SOCKET, SO_KEEPALIVE, (char *) &iOptVal, &iOptLen);
    if (iResult == SOCKET_ERROR) {
        wprintf(L"getsockopt for SO_KEEPALIVE failed with error: %u\n", WSAGetLastError());
    } else
        wprintf(L"SO_KEEPALIVE Value: %ld\n", iOptVal);

    closesocket(ListenSocket);
    WSACleanup();
    return 0;
}

Notes for IrDA Sockets

IrDA 向けの Windows ソケットを使用してアプリケーションを開発する際は、次の点に注意してください。

IRLMP_IAS_SET ソケットオプションを使用すると、アプリケーションはローカルの IAS 内で単一クラスの単一属性を設定できます。アプリケーションは、設定するクラス、属性、および属性の型を指定します。アプリケーションは、渡すパラメータに必要なサイズのバッファを割り当てることが求められます。

IrDA は、IrDA ベースの情報を格納する IAS データベースを提供します。IAS データベースへの限定的なアクセスは Windows Sockets 2 インターフェイスを通じて利用できますが、このようなアクセスは通常アプリケーションでは使用されず、主に Windows Sockets 2 の IrDA 規約に準拠していない非 Windows デバイスへの接続をサポートするために存在します。

次の構造体 IAS_SET は、ローカルの IAS データベースを管理するために IRLMP_IAS_SET setsockopt オプションとともに使用されます。


// #include <Af_irda.h> for this struct

typedef struct _IAS_SET {
    u_char      irdaClassName[IAS_MAX_CLASSNAME];
    char      irdaAttribName[IAS_MAX_ATTRIBNAME];
    u_long    irdaAttribType;
    union
    {
              LONG irdaAttribInt;
              struct
              {
                   u_long   Len;
                   u_char    OctetSeq[IAS_MAX_OCTET_STRING];
              } irdaAttribOctetSeq;
              struct
              {
                   u_long    Len;
                   u_long    CharSet;
                   u_char    UsrStr[IAS_MAX_USER_STRING];
              } irdaAttribUsrStr;
    } irdaAttribute;
} IAS_SET, *PIAS_SET, FAR *LPIASSET;

次の構造体 IAS_QUERY は、ピアの IAS データベースを照会するために IRLMP_IAS_QUERY setsockopt オプションとともに使用されます。


// #include <Af_irda.h> for this struct

typedef struct _WINDOWS_IAS_QUERY {
        u_char   irdaDeviceID[4];
        char     irdaClassName[IAS_MAX_CLASSNAME];
        char     irdaAttribName[IAS_MAX_ATTRIBNAME];
        u_long   irdaAttribType;
        union
        {
                  LONG    irdaAttribInt;
                  struct
                  {
                          u_long  Len;
                          u_char  OctetSeq[IAS_MAX_OCTET_STRING];
                  } irdaAttribOctetSeq;
                  struct
                  {
                          u_long  Len;
                          u_long  CharSet;
                          u_char  UsrStr[IAS_MAX_USER_STRING];
                  } irdaAttribUsrStr;
        } irdaAttribute;
} IAS_QUERY, *PIAS_QUERY, FAR *LPIASQUERY;

多くの SO_ レベルのソケットオプションは IrDA では意味を持ちません。SO_LINGER のみが明示的にサポートされています。

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

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

出典・ライセンス: 上記「公式ドキュメント」の内容は 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 setsockopt(
    SOCKET s,
    INT level,
    INT optname,
    LPCSTR optval,   // optional
    INT optlen
);
[DllImport("WS2_32.dll", SetLastError = true, ExactSpelling = true)]
static extern int setsockopt(
    UIntPtr s,   // SOCKET
    int level,   // INT
    int optname,   // INT
    [MarshalAs(UnmanagedType.LPStr)] string optval,   // LPCSTR optional
    int optlen   // INT
);
<DllImport("WS2_32.dll", SetLastError:=True, ExactSpelling:=True)>
Public Shared Function setsockopt(
    s As UIntPtr,   ' SOCKET
    level As Integer,   ' INT
    optname As Integer,   ' INT
    <MarshalAs(UnmanagedType.LPStr)> optval As String,   ' LPCSTR optional
    optlen As Integer   ' INT
) As Integer
End Function
' s : SOCKET
' level : INT
' optname : INT
' optval : LPCSTR optional
' optlen : INT
Declare PtrSafe Function setsockopt Lib "ws2_32" ( _
    ByVal s As LongPtr, _
    ByVal level As Long, _
    ByVal optname As Long, _
    ByVal optval As String, _
    ByVal optlen As Long) As Long
' VBA7前提(PtrSafe)。32bit Office では LongPtr→Long。Integer=16bit / Long=32bit / LongLong=64bit。
import ctypes
from ctypes import wintypes

setsockopt = ctypes.windll.ws2_32.setsockopt
setsockopt.restype = ctypes.c_int
setsockopt.argtypes = [
    ctypes.c_size_t,  # s : SOCKET
    ctypes.c_int,  # level : INT
    ctypes.c_int,  # optname : INT
    wintypes.LPCSTR,  # optval : LPCSTR optional
    ctypes.c_int,  # optlen : INT
]
# GetLastError: use ctypes.GetLastError() (or ctypes.WinDLL(use_last_error=True))
require 'fiddle'
require 'fiddle/import'

lib = Fiddle.dlopen('WS2_32.dll')
setsockopt = Fiddle::Function.new(
  lib['setsockopt'],
  [
    Fiddle::TYPE_UINTPTR_T,  # s : SOCKET
    Fiddle::TYPE_INT,  # level : INT
    Fiddle::TYPE_INT,  # optname : INT
    Fiddle::TYPE_VOIDP,  # optval : LPCSTR optional
    Fiddle::TYPE_INT,  # optlen : INT
  ],
  Fiddle::TYPE_INT)
#[link(name = "ws2_32")]
extern "system" {
    fn setsockopt(
        s: usize,  // SOCKET
        level: i32,  // INT
        optname: i32,  // INT
        optval: *const u8,  // LPCSTR optional
        optlen: i32  // INT
    ) -> i32;
}
// crates: windows-sys provides ready-made bindings for this API.
$sig = @"
[DllImport("WS2_32.dll", SetLastError = true)]
public static extern int setsockopt(UIntPtr s, int level, int optname, [MarshalAs(UnmanagedType.LPStr)] string optval, int optlen);
"@
$api = Add-Type -MemberDefinition $sig -Name 'WS2_32_setsockopt' -Namespace Win32 -PassThru
# $api::setsockopt(s, level, optname, optval, optlen)
#uselib "WS2_32.dll"
#func global setsockopt "setsockopt" sptr, sptr, sptr, sptr, sptr
; setsockopt s, level, optname, optval, optlen   ; 戻り値は stat
; s : SOCKET -> "sptr"
; level : INT -> "sptr"
; optname : INT -> "sptr"
; optval : LPCSTR optional -> "sptr"
; optlen : INT -> "sptr"
; ※HSP3.7は #func のため戻り値はシステム変数 stat に格納されます。
#uselib "WS2_32.dll"
#cfunc global setsockopt "setsockopt" sptr, int, int, str, int
; res = setsockopt(s, level, optname, optval, optlen)
; s : SOCKET -> "sptr"
; level : INT -> "int"
; optname : INT -> "int"
; optval : LPCSTR optional -> "str"
; optlen : INT -> "int"
; INT setsockopt(SOCKET s, INT level, INT optname, LPCSTR optval, INT optlen)
#uselib "WS2_32.dll"
#cfunc global setsockopt "setsockopt" intptr, int, int, str, int
; res = setsockopt(s, level, optname, optval, optlen)
; s : SOCKET -> "intptr"
; level : INT -> "int"
; optname : INT -> "int"
; optval : LPCSTR optional -> "str"
; optlen : INT -> "int"
import (
	"golang.org/x/sys/windows"
	"unsafe"
)

var (
	ws2_32 = windows.NewLazySystemDLL("WS2_32.dll")
	procsetsockopt = ws2_32.NewProc("setsockopt")
)

// s (SOCKET), level (INT), optname (INT), optval (LPCSTR optional), optlen (INT)
r1, _, err := procsetsockopt.Call(
	uintptr(s),
	uintptr(level),
	uintptr(optname),
	uintptr(unsafe.Pointer(windows.BytePtrFromString(optval))),
	uintptr(optlen),
)
_ = err  // syscall.Errno (valid when the call sets last-error)
_ = r1   // INT
function setsockopt(
  s: NativeUInt;   // SOCKET
  level: Integer;   // INT
  optname: Integer;   // INT
  optval: PAnsiChar;   // LPCSTR optional
  optlen: Integer   // INT
): Integer; stdcall;
  external 'WS2_32.dll' name 'setsockopt';
result := DllCall("WS2_32\setsockopt"
    , "UPtr", s   ; SOCKET
    , "Int", level   ; INT
    , "Int", optname   ; INT
    , "AStr", optval   ; LPCSTR optional
    , "Int", optlen   ; INT
    , "Int")   ; return: INT
●setsockopt(s, level, optname, optval, optlen) = DLL("WS2_32.dll", "int setsockopt(int, int, int, char*, int)")
# 呼び出し: setsockopt(s, level, optname, optval, optlen)
# s : SOCKET -> "int"
# level : INT -> "int"
# optname : INT -> "int"
# optval : LPCSTR optional -> "char*"
# optlen : INT -> "int"
# なでしこ1は32bit・ANSI(Shift_JIS)。文字列=char*(ANSI)、ポインタ/ハンドル=void*(4byte)。
const std = @import("std");

extern "ws2_32" fn setsockopt(
    s: usize, // SOCKET
    level: i32, // INT
    optname: i32, // INT
    optval: [*c]const u8, // LPCSTR optional
    optlen: i32 // INT
) callconv(std.os.windows.WINAPI) i32;
proc setsockopt(
    s: uint,  # SOCKET
    level: int32,  # INT
    optname: int32,  # INT
    optval: cstring,  # LPCSTR optional
    optlen: int32  # INT
): int32 {.importc: "setsockopt", stdcall, dynlib: "WS2_32.dll".}
pragma(lib, "ws2_32");
extern(Windows)
int setsockopt(
    size_t s,   // SOCKET
    int level,   // INT
    int optname,   // INT
    const(char)* optval,   // LPCSTR optional
    int optlen   // INT
);
ccall((:setsockopt, "WS2_32.dll"), stdcall, Int32,
      (Csize_t, Int32, Int32, Cstring, Int32),
      s, level, optname, optval, optlen)
# s : SOCKET -> Csize_t
# level : INT -> Int32
# optname : INT -> Int32
# optval : LPCSTR optional -> Cstring
# optlen : INT -> Int32
# stdcall は 32bit のみ意味を持つ(x64 では無視)。
local ffi = require("ffi")
ffi.cdef[[
int32_t setsockopt(
    uintptr_t s,
    int32_t level,
    int32_t optname,
    const char* optval,
    int32_t optlen);
]]
local ws2_32 = ffi.load("ws2_32")
-- ws2_32.setsockopt(s, level, optname, optval, optlen)
-- s : SOCKET
-- level : INT
-- optname : INT
-- optval : LPCSTR optional
-- optlen : INT
-- 構造体/GUIDへのポインタは cdef が通るよう void* で表記(実型は各引数コメント参照)。値渡し構造体・enum は対応する typedef を cdef に追加すること。
const koffi = require('koffi');
const lib = koffi.load('WS2_32.dll');
const setsockopt = lib.func('__stdcall', 'setsockopt', 'int32_t', ['uintptr_t', 'int32_t', 'int32_t', 'str', 'int32_t']);
// setsockopt(s, level, optname, optval, optlen)
// s : SOCKET -> 'uintptr_t'
// level : INT -> 'int32_t'
// optname : INT -> 'int32_t'
// optval : LPCSTR optional -> 'str'
// optlen : INT -> 'int32_t'
// 出力ポインタは koffi.out(...) で包む。構造体は koffi.struct で定義。
const lib = Deno.dlopen("WS2_32.dll", {
  setsockopt: { parameters: ["usize", "i32", "i32", "buffer", "i32"], result: "i32" },
});
// lib.symbols.setsockopt(s, level, optname, optval, optlen)
// s : SOCKET -> "usize"
// level : INT -> "i32"
// optname : INT -> "i32"
// optval : LPCSTR optional -> "buffer"
// optlen : INT -> "i32"
// 文字列引数は "buffer"(NUL 終端のバイト列を Uint8Array で渡す)。
// 値渡し構造体は { struct: [ ...field types... ] } を使用。
<?php
$ffi = FFI::cdef(<<<C
int32_t setsockopt(
    size_t s,
    int32_t level,
    int32_t optname,
    const char* optval,
    int32_t optlen);
C, "WS2_32.dll");
// $ffi->setsockopt(s, level, optname, optval, optlen);
// s : SOCKET
// level : INT
// optname : INT
// optval : LPCSTR optional
// optlen : 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 setsockopt(
        long s,   // SOCKET
        int level,   // INT
        int optname,   // INT
        String optval,   // LPCSTR optional
        int optlen   // INT
    );
}
@[Link("ws2_32")]
lib LibWS2_32
  fun setsockopt = setsockopt(
    s : LibC::SizeT,   # SOCKET
    level : Int32,   # INT
    optname : Int32,   # INT
    optval : UInt8*,   # LPCSTR optional
    optlen : 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 setsockoptNative = Int32 Function(UintPtr, Int32, Int32, Pointer<Utf8>, Int32);
typedef setsockoptDart = int Function(int, int, int, Pointer<Utf8>, int);
final setsockopt = DynamicLibrary.open('WS2_32.dll')
    .lookupFunction<setsockoptNative, setsockoptDart>('setsockopt');
// s : SOCKET -> UintPtr
// level : INT -> Int32
// optname : INT -> Int32
// optval : LPCSTR optional -> Pointer<Utf8>
// optlen : INT -> Int32
// 文字列は package:ffi の "...".toNativeUtf16()/toNativeUtf8() で変換。
{$mode objfpc}{$H+}
function setsockopt(
  s: NativeUInt;   // SOCKET
  level: Integer;   // INT
  optname: Integer;   // INT
  optval: PAnsiChar;   // LPCSTR optional
  optlen: Integer   // INT
): Integer; stdcall;
  external 'WS2_32.dll' name 'setsockopt';
import Foreign
import Foreign.C.Types
import Foreign.C.String

foreign import stdcall safe "setsockopt"
  c_setsockopt :: CUIntPtr -> Int32 -> Int32 -> CString -> Int32 -> IO Int32
-- s : SOCKET -> CUIntPtr
-- level : INT -> Int32
-- optname : INT -> Int32
-- optval : LPCSTR optional -> CString
-- optlen : INT -> Int32
-- 要 GHC(Windows)。stdcall は x64 では ccall として扱われる。ブロックする API は safe 呼び出し推奨。
open Ctypes
open Foreign

let setsockopt =
  foreign "setsockopt"
    (size_t @-> int32_t @-> int32_t @-> string @-> int32_t @-> returning int32_t)
(* s : SOCKET -> size_t *)
(* level : INT -> int32_t *)
(* optname : INT -> int32_t *)
(* optval : LPCSTR optional -> string *)
(* optlen : 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 ("setsockopt" setsockopt :convention :stdcall) :int32
  (s :uint64)   ; SOCKET
  (level :int32)   ; INT
  (optname :int32)   ; INT
  (optval :string)   ; LPCSTR optional
  (optlen :int32))   ; INT
; isize/usize(INT_PTR/SIZE_T)は x64 前提で :int64/:uint64。x86 では :int32/:uint32。
use Win32::API;
my $setsockopt = Win32::API::More->new('WS2_32',
    'int setsockopt(WPARAM s, int level, int optname, LPCSTR optval, int optlen)');
# my $ret = $setsockopt->Call($s, $level, $optname, $optval, $optlen);
# s : SOCKET -> WPARAM
# level : INT -> int
# optname : INT -> int
# optval : LPCSTR optional -> LPCSTR
# optlen : INT -> int
# 値渡し構造体は pack() した文字列、または Win32::API::Struct を使用。

関連項目

公式の関連項目