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

WSAConnect

関数
接続データやQoS指定付きで相手に接続する。
DLLWS2_32.dll呼出規約winapiSetLastErrorあり対応OSWindows 8.1 以降

シグネチャ

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

INT WSAConnect(
    SOCKET s,
    const SOCKADDR* name,
    INT namelen,
    WSABUF* lpCallerData,   // optional
    WSABUF* lpCalleeData,   // optional
    QOS* lpSQOS,   // optional
    QOS* lpGQOS   // optional
);

パラメーター

名前方向説明
sSOCKETin未接続のソケットを識別するディスクリプタ。
nameSOCKADDR*in接続先アドレスを指定する sockaddr 構造体へのポインタ。IPv4 の場合、sockaddr にはアドレスファミリとして AF_INET、宛先 IPv4 アドレス、宛先ポートが含まれます。IPv6 の場合、sockaddr 構造体にはアドレスファミリとして AF_INET6、宛先 IPv6 アドレス、宛先ポートが含まれ、さらにフロー情報やスコープ ID 情報が含まれることもあります。
namelenINTinname パラメータが指す sockaddr 構造体の長さ (バイト単位)。
lpCallerDataWSABUF*inoptional接続確立時に相手側ソケットへ転送されるユーザーデータへのポインタ。「解説」を参照してください。
lpCalleeDataWSABUF*outoptional接続確立時に相手側ソケットから返送されるユーザーデータへのポインタ。「解説」を参照してください。
lpSQOSQOS*inoptionalソケット s に対する QOS 構造体へのポインタ。
lpGQOSQOS*inoptional将来のソケットグループでの使用のために予約されています。ソケットグループ (該当する場合) に対する QOS 構造体へのポインタ。このパラメータは NULL にする必要があります。

戻り値の型: INT

公式ドキュメント

WSAConnect 関数は、別のソケットアプリケーションへの接続を確立し、接続データを交換するとともに、指定された FLOWSPEC 構造体に基づいて必要なサービス品質 (QoS) を指定します。

戻り値

エラーが発生しなかった場合、 WSAConnect はゼロを返します。それ以外の場合は SOCKET_ERROR を返し、 WSAGetLastError を呼び出すことで具体的なエラーコードを取得できます。ブロッキングソケットでは、戻り値は接続試行の成否を示します。

非ブロッキングソケットでは、接続試行を即座に完了できません。この場合、 WSAConnectSOCKET_ERROR を返し、 WSAGetLastErrorWSAEWOULDBLOCK を返します。このため、アプリケーションでは次のいずれかの方法を取ることができます。

非ブロッキングソケットでは、接続試行が完了するまで、同じソケットに対する以降の WSAConnect 呼び出しはすべてエラーコード WSAEALREADY で失敗します。

戻り値のエラーコードが接続試行の失敗を示している場合 (すなわち WSAECONNREFUSEDWSAENETUNREACHWSAETIMEDOUT)、アプリケーションは同じソケットに対して再び WSAConnect を呼び出すことができます。

エラーコード 意味
WSANOTINITIALISED
この関数を使用する前に、 WSAStartup の呼び出しが正常に完了している必要があります。
WSAENETDOWN
ネットワークサブシステムに障害が発生しました。
WSAEADDRINUSE
ソケットのローカルアドレスが既に使用中で、かつソケットが SO_REUSEADDR によるアドレス再利用を許可するようにマークされていません。このエラーは通常 bind の実行中に発生しますが、bind 関数がワイルドカードを含む部分的なアドレス (ADDR_ANY を含む) を扱い、この関数の時点で特定のアドレスを「確定」する必要がある場合には、この関数まで遅延することがあります。
WSAEINTR
(ブロッキングの) Windows Socket 1.1 呼び出しが WSACancelBlockingCall によってキャンセルされました。
WSAEINPROGRESS
ブロッキングの Windows Sockets 1.1 呼び出しが進行中であるか、サービスプロバイダーがまだコールバック関数を処理しています。
WSAEALREADY
指定されたソケットで、非ブロッキングの connect または WSAConnect 呼び出しが進行中です。
WSAEADDRNOTAVAIL
リモートアドレスが有効なアドレスではありません (ADDR_ANY など)。
WSAEAFNOSUPPORT
指定されたファミリのアドレスは、このソケットでは使用できません。
WSAECONNREFUSED
接続の試行が拒否されました。
WSAEFAULT
name または namelen パラメータがユーザーアドレス空間の有効な部分ではない、namelen パラメータが小さすぎる、lpCalleeDatalpSQOSlpGQOS のバッファ長が小さすぎる、または lpCallerData のバッファ長が大きすぎます。
WSAEINVAL
パラメータ s がリッスン中のソケットである、指定された宛先アドレスがソケットの属する制約付きグループのものと整合していない、または lpGQOS パラメータが NULL ではありません。
WSAEISCONN
ソケットは既に接続されています (コネクション指向のソケットのみ)。
WSAENETUNREACH
現時点で、このホストからネットワークに到達できません。
WSAEHOSTUNREACH
到達不能なホストに対してソケット操作が試みられました。
WSAENOBUFS
利用可能なバッファ領域がありません。ソケットを接続できません。
WSAENOTSOCK
ディスクリプタがソケットではありません。
WSAEOPNOTSUPP
lpSQOS および lpGQOS で指定された FLOWSPEC 構造体を満たすことができません。
WSAEPROTONOSUPPORT
lpCallerData パラメータはサービスプロバイダーでサポートされていません。
WSAETIMEDOUT
接続を確立できないまま、接続の試行がタイムアウトしました。
WSAEWOULDBLOCK
ソケットが非ブロッキングとしてマークされており、接続を即座に完了できません。
WSAEACCES
setsockoptSO_BROADCAST が有効になっていないため、データグラムソケットをブロードキャストアドレスに接続する試行が失敗しました。

解説(Remarks)

WSAConnect 関数は、指定された宛先への接続を作成し、接続時に発生するその他のいくつかの付随的な操作を実行するために使用されます。ソケット s がバインドされていない場合、システムによってローカルの関連付けに一意の値が割り当てられ、ソケットはバインド済みとしてマークされます。

Windows Vista 以降を対象とするアプリケーションでは、クライアントアプリケーションの設計を大幅に簡素化できる WSAConnectByList 関数または WSAConnectByName 関数の使用を検討してください。

コネクション指向のソケット (たとえば type SOCK_STREAM) の場合、name (ソケットの名前空間内のアドレス。詳細な説明については bind を参照してください) を使用して、リモートホストへのアクティブな接続が開始されます。この呼び出しが正常に完了すると、ソケットはデータの送受信が可能になります。name 構造体のアドレスパラメータがすべてゼロの場合、 WSAConnect はエラー WSAEADDRNOTAVAIL を返します。アクティブな接続を再接続しようとすると、エラーコード WSAEISCONN で失敗します。

ソケットを開き、 setsockopt 呼び出しを行ってから sendto 呼び出しを行うと、Windows Sockets は暗黙的な bind 関数呼び出しを実行します。
コネクション指向の非ブロッキングソケットでは、接続を即座に完了できないことがよくあります。このような場合、この関数はエラー WSAEWOULDBLOCK を返しますが、操作自体は進行します。成功または失敗の結果が判明すると、クライアントが通知をどのように登録しているかに応じて、いくつかの方法のいずれかで報告されます。クライアントが select を使用している場合、成功は writefds セットで、失敗は exceptfds セットで報告されます。クライアントが WSAAsyncSelect または WSAEventSelect を使用している場合、通知は FD_CONNECT で通知され、FD_CONNECT に関連付けられたエラーコードが、成功または失敗の具体的な原因を示します。

コネクションレスソケット (たとえば type SOCK_DGRAM) の場合、 WSAConnect が実行する操作は、既定の宛先アドレスを確立することだけであり、これによりソケットを以降のコネクション指向の送受信操作 (sendWSASendrecvWSARecv) で使用できるようになります。指定された宛先アドレス以外のアドレスから受信したデータグラムは破棄されます。name 構造体全体がすべてゼロの場合 (name 構造体のアドレスパラメータだけでなく)、ソケットは切断されます。その後、既定のリモートアドレスは未定となるため、sendWSASendrecvWSARecv の呼び出しはエラーコード WSAENOTCONN を返します。ただし、 sendtoWSASendTorecvfromWSARecvFrom は引き続き使用できます。既定の宛先は、ソケットが既に接続済みであっても、単に WSAConnect を再度呼び出すことで変更できます。受信用にキューイングされているデータグラムは、name が前回の WSAConnect と異なる場合に破棄されます。

コネクションレスソケットでは、name はブロードキャストアドレスを含む任意の有効なアドレスを指定できます。ただし、ブロードキャストアドレスに接続するには、ソケットで setsockoptSO_BROADCAST が有効になっている必要があります。そうでない場合、 WSAConnect はエラーコード WSAEACCES で失敗します。

コネクションレスソケットでは、ユーザー間のデータ交換はできず、対応するパラメータは黙って無視されます。

アプリケーションは、指定する各パラメータが直接または間接的に指すメモリ領域の割り当てに責任を負います。

lpCallerData パラメータは、接続要求とともに送信される任意のユーザーデータ (接続データと呼ばれます) へのポインタを含みます。これは通常のネットワークデータストリームには含まれない追加データであり、接続を確立するためのネットワーク要求とともに送信されます。このオプションは、DECNet、OSI TP4 などのレガシープロトコルで使用されます。

接続データは、Windows の TCP/IP プロトコルではサポートされていません。接続データは、raw ソケット上の ATM (RAWWAN) でのみサポートされます。

lpCallerDataNULL の場合、ユーザーデータはピアに渡されません。lpCalleeData は結果パラメータであり、接続確立の一部として相手側ソケットから返送される任意のユーザーデータを WSABUF 構造体として格納します。lpCalleeData パラメータが指す WSABUF 構造体の len メンバには、初期状態では、アプリケーションが WSABUF 構造体の buf メンバ用に割り当てたバッファの長さが格納されます。ユーザーデータが返送されなかった場合、lpCalleeData パラメータが指す WSABUF 構造体の len メンバはゼロに設定されます。lpCalleeData の情報は、接続操作が完了した時点で有効になります。ブロッキングソケットの場合、接続操作は WSAConnect 関数が戻った時点で完了します。非ブロッキングソケットの場合、FD_CONNECT 通知が発生した後に完了します。lpCalleeDataNULL の場合、ユーザーデータは返送されません。ユーザーデータの正確な形式は、ソケットが属するアドレスファミリに固有です。

接続時に、アプリケーションは lpSQOS および lpGQOS パラメータを使用して、 WSAIoctlSIO_SET_QOS または SIO_SET_GROUP_QOS オペコードを使用して以前にソケットに対して行ったサービス品質の指定を上書きできます。

lpSQOS パラメータは、ソケット s に対する FLOWSPEC 構造体を、方向ごとに 1 つずつ指定し、続いて追加のプロバイダー固有パラメータを指定します。関連するトランスポートプロバイダー全体、または特定の種類のソケットがサービス品質の要求を満たせない場合、以下に示すようにエラーが返されます。単方向ソケットの場合、それぞれ送信または受信のフロー仕様の値は無視されます。プロバイダー固有のパラメータが指定されない場合、lpCalleeData パラメータが指す WSABUF 構造体の buf および len メンバは、それぞれ NULL およびゼロに設定する必要があります。lpSQOS パラメータが NULL の場合、アプリケーションによるサービス品質の指定がないことを示します。

将来のソケットグループでの使用のために予約されています。lpGQOS は、ソケットグループ (該当する場合) に対する FLOWSPEC 構造体を、方向ごとに 1 つずつ指定し、続いて追加のプロバイダー固有パラメータを指定します。プロバイダー固有のパラメータが指定されない場合、lpCalleeData パラメータが指す WSABUF 構造体の buf および len メンバは、それぞれ NULL およびゼロに設定する必要があります。lpGQOSNULL の場合、アプリケーションによるグループのサービス品質の指定がないことを示します。このパラメータは、s がソケットグループの作成者でない場合は無視されます。

接続済みのソケットが何らかの理由で閉じられた場合、それらは破棄して再作成する必要があります。接続済みのソケットで何らかの理由で問題が発生した場合は、安定した状態に戻すために、アプリケーションが必要なソケットを破棄して再作成しなければならないと想定するのが最も安全です。

WSAConnect のようなブロッキング Winsock 呼び出しを発行する場合、Winsock は呼び出しを完了できるようになる前にネットワークイベントを待機する必要がある場合があります。この状況では Winsock はアラート可能な待機を実行し、これは同じスレッドでスケジュールされた非同期プロシージャ呼び出し (APC) によって中断される可能性があります。同じスレッド上で進行中のブロッキング Winsock 呼び出しを中断した APC 内で別のブロッキング Winsock 呼び出しを発行すると、未定義の動作につながるため、Winsock クライアントが決して試みてはなりません。
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 WSAConnect(
    SOCKET s,
    const SOCKADDR* name,
    INT namelen,
    WSABUF* lpCallerData,   // optional
    WSABUF* lpCalleeData,   // optional
    QOS* lpSQOS,   // optional
    QOS* lpGQOS   // optional
);
[DllImport("WS2_32.dll", SetLastError = true, ExactSpelling = true)]
static extern int WSAConnect(
    UIntPtr s,   // SOCKET
    IntPtr name,   // SOCKADDR*
    int namelen,   // INT
    IntPtr lpCallerData,   // WSABUF* optional
    IntPtr lpCalleeData,   // WSABUF* optional, out
    IntPtr lpSQOS,   // QOS* optional
    IntPtr lpGQOS   // QOS* optional
);
<DllImport("WS2_32.dll", SetLastError:=True, ExactSpelling:=True)>
Public Shared Function WSAConnect(
    s As UIntPtr,   ' SOCKET
    name As IntPtr,   ' SOCKADDR*
    namelen As Integer,   ' INT
    lpCallerData As IntPtr,   ' WSABUF* optional
    lpCalleeData As IntPtr,   ' WSABUF* optional, out
    lpSQOS As IntPtr,   ' QOS* optional
    lpGQOS As IntPtr   ' QOS* optional
) As Integer
End Function
' s : SOCKET
' name : SOCKADDR*
' namelen : INT
' lpCallerData : WSABUF* optional
' lpCalleeData : WSABUF* optional, out
' lpSQOS : QOS* optional
' lpGQOS : QOS* optional
Declare PtrSafe Function WSAConnect Lib "ws2_32" ( _
    ByVal s As LongPtr, _
    ByVal name As LongPtr, _
    ByVal namelen As Long, _
    ByVal lpCallerData As LongPtr, _
    ByVal lpCalleeData As LongPtr, _
    ByVal lpSQOS As LongPtr, _
    ByVal lpGQOS As LongPtr) As Long
' VBA7前提(PtrSafe)。32bit Office では LongPtr→Long。Integer=16bit / Long=32bit / LongLong=64bit。
import ctypes
from ctypes import wintypes

WSAConnect = ctypes.windll.ws2_32.WSAConnect
WSAConnect.restype = ctypes.c_int
WSAConnect.argtypes = [
    ctypes.c_size_t,  # s : SOCKET
    ctypes.c_void_p,  # name : SOCKADDR*
    ctypes.c_int,  # namelen : INT
    ctypes.c_void_p,  # lpCallerData : WSABUF* optional
    ctypes.c_void_p,  # lpCalleeData : WSABUF* optional, out
    ctypes.c_void_p,  # lpSQOS : QOS* optional
    ctypes.c_void_p,  # lpGQOS : QOS* optional
]
# GetLastError: use ctypes.GetLastError() (or ctypes.WinDLL(use_last_error=True))
require 'fiddle'
require 'fiddle/import'

lib = Fiddle.dlopen('WS2_32.dll')
WSAConnect = Fiddle::Function.new(
  lib['WSAConnect'],
  [
    Fiddle::TYPE_UINTPTR_T,  # s : SOCKET
    Fiddle::TYPE_VOIDP,  # name : SOCKADDR*
    Fiddle::TYPE_INT,  # namelen : INT
    Fiddle::TYPE_VOIDP,  # lpCallerData : WSABUF* optional
    Fiddle::TYPE_VOIDP,  # lpCalleeData : WSABUF* optional, out
    Fiddle::TYPE_VOIDP,  # lpSQOS : QOS* optional
    Fiddle::TYPE_VOIDP,  # lpGQOS : QOS* optional
  ],
  Fiddle::TYPE_INT)
#[link(name = "ws2_32")]
extern "system" {
    fn WSAConnect(
        s: usize,  // SOCKET
        name: *const SOCKADDR,  // SOCKADDR*
        namelen: i32,  // INT
        lpCallerData: *mut WSABUF,  // WSABUF* optional
        lpCalleeData: *mut WSABUF,  // WSABUF* optional, out
        lpSQOS: *mut QOS,  // QOS* optional
        lpGQOS: *mut QOS  // QOS* optional
    ) -> i32;
}
// crates: windows-sys provides ready-made bindings for this API.
$sig = @"
[DllImport("WS2_32.dll", SetLastError = true)]
public static extern int WSAConnect(UIntPtr s, IntPtr name, int namelen, IntPtr lpCallerData, IntPtr lpCalleeData, IntPtr lpSQOS, IntPtr lpGQOS);
"@
$api = Add-Type -MemberDefinition $sig -Name 'WS2_32_WSAConnect' -Namespace Win32 -PassThru
# $api::WSAConnect(s, name, namelen, lpCallerData, lpCalleeData, lpSQOS, lpGQOS)
#uselib "WS2_32.dll"
#func global WSAConnect "WSAConnect" sptr, sptr, sptr, sptr, sptr, sptr, sptr
; WSAConnect s, varptr(name), namelen, varptr(lpCallerData), varptr(lpCalleeData), varptr(lpSQOS), varptr(lpGQOS)   ; 戻り値は stat
; s : SOCKET -> "sptr"
; name : SOCKADDR* -> "sptr"
; namelen : INT -> "sptr"
; lpCallerData : WSABUF* optional -> "sptr"
; lpCalleeData : WSABUF* optional, out -> "sptr"
; lpSQOS : QOS* optional -> "sptr"
; lpGQOS : QOS* optional -> "sptr"
; ※HSP3.7は #func のため戻り値はシステム変数 stat に格納されます。
出力引数:
#uselib "WS2_32.dll"
#cfunc global WSAConnect "WSAConnect" sptr, var, int, var, var, var, var
; res = WSAConnect(s, name, namelen, lpCallerData, lpCalleeData, lpSQOS, lpGQOS)
; s : SOCKET -> "sptr"
; name : SOCKADDR* -> "var"
; namelen : INT -> "int"
; lpCallerData : WSABUF* optional -> "var"
; lpCalleeData : WSABUF* optional, out -> "var"
; lpSQOS : QOS* optional -> "var"
; lpGQOS : QOS* optional -> "var"
; ※出力/バッファ引数は var 方式(変数を直接渡す)。varptr 方式にも切替可。
出力引数:
; INT WSAConnect(SOCKET s, SOCKADDR* name, INT namelen, WSABUF* lpCallerData, WSABUF* lpCalleeData, QOS* lpSQOS, QOS* lpGQOS)
#uselib "WS2_32.dll"
#cfunc global WSAConnect "WSAConnect" intptr, var, int, var, var, var, var
; res = WSAConnect(s, name, namelen, lpCallerData, lpCalleeData, lpSQOS, lpGQOS)
; s : SOCKET -> "intptr"
; name : SOCKADDR* -> "var"
; namelen : INT -> "int"
; lpCallerData : WSABUF* optional -> "var"
; lpCalleeData : WSABUF* optional, out -> "var"
; lpSQOS : QOS* optional -> "var"
; lpGQOS : QOS* optional -> "var"
; ※出力/バッファ引数は var 方式(変数を直接渡す)。varptr 方式にも切替可。
import (
	"golang.org/x/sys/windows"
	"unsafe"
)

var (
	ws2_32 = windows.NewLazySystemDLL("WS2_32.dll")
	procWSAConnect = ws2_32.NewProc("WSAConnect")
)

// s (SOCKET), name (SOCKADDR*), namelen (INT), lpCallerData (WSABUF* optional), lpCalleeData (WSABUF* optional, out), lpSQOS (QOS* optional), lpGQOS (QOS* optional)
r1, _, err := procWSAConnect.Call(
	uintptr(s),
	uintptr(name),
	uintptr(namelen),
	uintptr(lpCallerData),
	uintptr(lpCalleeData),
	uintptr(lpSQOS),
	uintptr(lpGQOS),
)
_ = err  // syscall.Errno (valid when the call sets last-error)
_ = r1   // INT
function WSAConnect(
  s: NativeUInt;   // SOCKET
  name: Pointer;   // SOCKADDR*
  namelen: Integer;   // INT
  lpCallerData: Pointer;   // WSABUF* optional
  lpCalleeData: Pointer;   // WSABUF* optional, out
  lpSQOS: Pointer;   // QOS* optional
  lpGQOS: Pointer   // QOS* optional
): Integer; stdcall;
  external 'WS2_32.dll' name 'WSAConnect';
result := DllCall("WS2_32\WSAConnect"
    , "UPtr", s   ; SOCKET
    , "Ptr", name   ; SOCKADDR*
    , "Int", namelen   ; INT
    , "Ptr", lpCallerData   ; WSABUF* optional
    , "Ptr", lpCalleeData   ; WSABUF* optional, out
    , "Ptr", lpSQOS   ; QOS* optional
    , "Ptr", lpGQOS   ; QOS* optional
    , "Int")   ; return: INT
●WSAConnect(s, name, namelen, lpCallerData, lpCalleeData, lpSQOS, lpGQOS) = DLL("WS2_32.dll", "int WSAConnect(int, void*, int, void*, void*, void*, void*)")
# 呼び出し: WSAConnect(s, name, namelen, lpCallerData, lpCalleeData, lpSQOS, lpGQOS)
# s : SOCKET -> "int"
# name : SOCKADDR* -> "void*"
# namelen : INT -> "int"
# lpCallerData : WSABUF* optional -> "void*"
# lpCalleeData : WSABUF* optional, out -> "void*"
# lpSQOS : QOS* optional -> "void*"
# lpGQOS : QOS* optional -> "void*"
# なでしこ1は32bit・ANSI(Shift_JIS)。文字列=char*(ANSI)、ポインタ/ハンドル=void*(4byte)。
const std = @import("std");

extern "ws2_32" fn WSAConnect(
    s: usize, // SOCKET
    name: [*c]SOCKADDR, // SOCKADDR*
    namelen: i32, // INT
    lpCallerData: [*c]WSABUF, // WSABUF* optional
    lpCalleeData: [*c]WSABUF, // WSABUF* optional, out
    lpSQOS: [*c]QOS, // QOS* optional
    lpGQOS: [*c]QOS // QOS* optional
) callconv(std.os.windows.WINAPI) i32;
proc WSAConnect(
    s: uint,  # SOCKET
    name: ptr SOCKADDR,  # SOCKADDR*
    namelen: int32,  # INT
    lpCallerData: ptr WSABUF,  # WSABUF* optional
    lpCalleeData: ptr WSABUF,  # WSABUF* optional, out
    lpSQOS: ptr QOS,  # QOS* optional
    lpGQOS: ptr QOS  # QOS* optional
): int32 {.importc: "WSAConnect", stdcall, dynlib: "WS2_32.dll".}
pragma(lib, "ws2_32");
extern(Windows)
int WSAConnect(
    size_t s,   // SOCKET
    SOCKADDR* name,   // SOCKADDR*
    int namelen,   // INT
    WSABUF* lpCallerData,   // WSABUF* optional
    WSABUF* lpCalleeData,   // WSABUF* optional, out
    QOS* lpSQOS,   // QOS* optional
    QOS* lpGQOS   // QOS* optional
);
ccall((:WSAConnect, "WS2_32.dll"), stdcall, Int32,
      (Csize_t, Ptr{SOCKADDR}, Int32, Ptr{WSABUF}, Ptr{WSABUF}, Ptr{QOS}, Ptr{QOS}),
      s, name, namelen, lpCallerData, lpCalleeData, lpSQOS, lpGQOS)
# s : SOCKET -> Csize_t
# name : SOCKADDR* -> Ptr{SOCKADDR}
# namelen : INT -> Int32
# lpCallerData : WSABUF* optional -> Ptr{WSABUF}
# lpCalleeData : WSABUF* optional, out -> Ptr{WSABUF}
# lpSQOS : QOS* optional -> Ptr{QOS}
# lpGQOS : QOS* optional -> Ptr{QOS}
# stdcall は 32bit のみ意味を持つ(x64 では無視)。
local ffi = require("ffi")
ffi.cdef[[
int32_t WSAConnect(
    uintptr_t s,
    void* name,
    int32_t namelen,
    void* lpCallerData,
    void* lpCalleeData,
    void* lpSQOS,
    void* lpGQOS);
]]
local ws2_32 = ffi.load("ws2_32")
-- ws2_32.WSAConnect(s, name, namelen, lpCallerData, lpCalleeData, lpSQOS, lpGQOS)
-- s : SOCKET
-- name : SOCKADDR*
-- namelen : INT
-- lpCallerData : WSABUF* optional
-- lpCalleeData : WSABUF* optional, out
-- lpSQOS : QOS* optional
-- lpGQOS : QOS* optional
-- 構造体/GUIDへのポインタは cdef が通るよう void* で表記(実型は各引数コメント参照)。値渡し構造体・enum は対応する typedef を cdef に追加すること。
const koffi = require('koffi');
const lib = koffi.load('WS2_32.dll');
const WSAConnect = lib.func('__stdcall', 'WSAConnect', 'int32_t', ['uintptr_t', 'void *', 'int32_t', 'void *', 'void *', 'void *', 'void *']);
// WSAConnect(s, name, namelen, lpCallerData, lpCalleeData, lpSQOS, lpGQOS)
// s : SOCKET -> 'uintptr_t'
// name : SOCKADDR* -> 'void *'
// namelen : INT -> 'int32_t'
// lpCallerData : WSABUF* optional -> 'void *'
// lpCalleeData : WSABUF* optional, out -> 'void *'
// lpSQOS : QOS* optional -> 'void *'
// lpGQOS : QOS* optional -> 'void *'
// 出力ポインタは koffi.out(...) で包む。構造体は koffi.struct で定義。
const lib = Deno.dlopen("WS2_32.dll", {
  WSAConnect: { parameters: ["usize", "pointer", "i32", "pointer", "pointer", "pointer", "pointer"], result: "i32" },
});
// lib.symbols.WSAConnect(s, name, namelen, lpCallerData, lpCalleeData, lpSQOS, lpGQOS)
// s : SOCKET -> "usize"
// name : SOCKADDR* -> "pointer"
// namelen : INT -> "i32"
// lpCallerData : WSABUF* optional -> "pointer"
// lpCalleeData : WSABUF* optional, out -> "pointer"
// lpSQOS : QOS* optional -> "pointer"
// lpGQOS : QOS* optional -> "pointer"
// 文字列引数は "buffer"(NUL 終端のバイト列を Uint8Array で渡す)。
// 値渡し構造体は { struct: [ ...field types... ] } を使用。
<?php
$ffi = FFI::cdef(<<<C
int32_t WSAConnect(
    size_t s,
    void* name,
    int32_t namelen,
    void* lpCallerData,
    void* lpCalleeData,
    void* lpSQOS,
    void* lpGQOS);
C, "WS2_32.dll");
// $ffi->WSAConnect(s, name, namelen, lpCallerData, lpCalleeData, lpSQOS, lpGQOS);
// s : SOCKET
// name : SOCKADDR*
// namelen : INT
// lpCallerData : WSABUF* optional
// lpCalleeData : WSABUF* optional, out
// lpSQOS : QOS* optional
// lpGQOS : QOS* optional
// 構造体/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 WSAConnect(
        long s,   // SOCKET
        Pointer name,   // SOCKADDR*
        int namelen,   // INT
        Pointer lpCallerData,   // WSABUF* optional
        Pointer lpCalleeData,   // WSABUF* optional, out
        Pointer lpSQOS,   // QOS* optional
        Pointer lpGQOS   // QOS* optional
    );
}
@[Link("ws2_32")]
lib LibWS2_32
  fun WSAConnect = WSAConnect(
    s : LibC::SizeT,   # SOCKET
    name : SOCKADDR*,   # SOCKADDR*
    namelen : Int32,   # INT
    lpCallerData : WSABUF*,   # WSABUF* optional
    lpCalleeData : WSABUF*,   # WSABUF* optional, out
    lpSQOS : QOS*,   # QOS* optional
    lpGQOS : QOS*   # QOS* optional
  ) : Int32
end
# 構造体/GUID/enum は lib 内に対応する型定義が必要。
# 呼出規約: x64 は規約統一のため OK。x86(32bit)は WINAPI=stdcall だが Crystal の fun に stdcall 付与構文がなく非対応。
import 'dart:ffi';
import 'package:ffi/ffi.dart';

typedef WSAConnectNative = Int32 Function(UintPtr, Pointer<Void>, Int32, Pointer<Void>, Pointer<Void>, Pointer<Void>, Pointer<Void>);
typedef WSAConnectDart = int Function(int, Pointer<Void>, int, Pointer<Void>, Pointer<Void>, Pointer<Void>, Pointer<Void>);
final WSAConnect = DynamicLibrary.open('WS2_32.dll')
    .lookupFunction<WSAConnectNative, WSAConnectDart>('WSAConnect');
// s : SOCKET -> UintPtr
// name : SOCKADDR* -> Pointer<Void>
// namelen : INT -> Int32
// lpCallerData : WSABUF* optional -> Pointer<Void>
// lpCalleeData : WSABUF* optional, out -> Pointer<Void>
// lpSQOS : QOS* optional -> Pointer<Void>
// lpGQOS : QOS* optional -> Pointer<Void>
// 文字列は package:ffi の "...".toNativeUtf16()/toNativeUtf8() で変換。
{$mode objfpc}{$H+}
function WSAConnect(
  s: NativeUInt;   // SOCKET
  name: Pointer;   // SOCKADDR*
  namelen: Integer;   // INT
  lpCallerData: Pointer;   // WSABUF* optional
  lpCalleeData: Pointer;   // WSABUF* optional, out
  lpSQOS: Pointer;   // QOS* optional
  lpGQOS: Pointer   // QOS* optional
): Integer; stdcall;
  external 'WS2_32.dll' name 'WSAConnect';
import Foreign
import Foreign.C.Types
import Foreign.C.String

foreign import stdcall safe "WSAConnect"
  c_WSAConnect :: CUIntPtr -> Ptr () -> Int32 -> Ptr () -> Ptr () -> Ptr () -> Ptr () -> IO Int32
-- s : SOCKET -> CUIntPtr
-- name : SOCKADDR* -> Ptr ()
-- namelen : INT -> Int32
-- lpCallerData : WSABUF* optional -> Ptr ()
-- lpCalleeData : WSABUF* optional, out -> Ptr ()
-- lpSQOS : QOS* optional -> Ptr ()
-- lpGQOS : QOS* optional -> Ptr ()
-- 要 GHC(Windows)。stdcall は x64 では ccall として扱われる。ブロックする API は safe 呼び出し推奨。
open Ctypes
open Foreign

let wsaconnect =
  foreign "WSAConnect"
    (size_t @-> (ptr void) @-> int32_t @-> (ptr void) @-> (ptr void) @-> (ptr void) @-> (ptr void) @-> returning int32_t)
(* s : SOCKET -> size_t *)
(* name : SOCKADDR* -> (ptr void) *)
(* namelen : INT -> int32_t *)
(* lpCallerData : WSABUF* optional -> (ptr void) *)
(* lpCalleeData : WSABUF* optional, out -> (ptr void) *)
(* lpSQOS : QOS* optional -> (ptr void) *)
(* lpGQOS : QOS* optional -> (ptr void) *)
(* 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 ("WSAConnect" wsaconnect :convention :stdcall) :int32
  (s :uint64)   ; SOCKET
  (name :pointer)   ; SOCKADDR*
  (namelen :int32)   ; INT
  (lp-caller-data :pointer)   ; WSABUF* optional
  (lp-callee-data :pointer)   ; WSABUF* optional, out
  (lp-sqos :pointer)   ; QOS* optional
  (lp-gqos :pointer))   ; QOS* optional
; isize/usize(INT_PTR/SIZE_T)は x64 前提で :int64/:uint64。x86 では :int32/:uint32。
use Win32::API;
my $WSAConnect = Win32::API::More->new('WS2_32',
    'int WSAConnect(WPARAM s, LPVOID name, int namelen, LPVOID lpCallerData, LPVOID lpCalleeData, LPVOID lpSQOS, LPVOID lpGQOS)');
# my $ret = $WSAConnect->Call($s, $name, $namelen, $lpCallerData, $lpCalleeData, $lpSQOS, $lpGQOS);
# s : SOCKET -> WPARAM
# name : SOCKADDR* -> LPVOID
# namelen : INT -> int
# lpCallerData : WSABUF* optional -> LPVOID
# lpCalleeData : WSABUF* optional, out -> LPVOID
# lpSQOS : QOS* optional -> LPVOID
# lpGQOS : QOS* optional -> LPVOID
# 値渡し構造体は pack() した文字列、または Win32::API::Struct を使用。

関連項目

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