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

WSARecv

関数
接続済みソケットからデータを受信する。
DLLWS2_32.dll呼出規約winapiSetLastErrorあり対応OSWindows 8.1 以降

シグネチャ

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

INT WSARecv(
    SOCKET s,
    WSABUF* lpBuffers,
    DWORD dwBufferCount,
    DWORD* lpNumberOfBytesRecvd,   // optional
    DWORD* lpFlags,
    OVERLAPPED* lpOverlapped,   // optional
    LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine   // optional
);

パラメーター

名前方向説明
sSOCKETin接続済みソケットを識別するディスクリプタ。
lpBuffersWSABUF*inWSABUF 構造体の配列へのポインタ。各 WSABUF 構造体には、バッファへのポインタと、そのバッファの長さ(バイト単位)が格納されます。
dwBufferCountDWORDinlpBuffers 配列内の WSABUF 構造体の数。
lpNumberOfBytesRecvdDWORD*outoptional

受信操作がただちに完了した場合に、この呼び出しで受信したデータのバイト数を受け取るポインタ。

誤った結果を避けるため、lpOverlapped パラメーターが NULL でない場合は、このパラメーターに NULL を指定してください。このパラメーターを NULL にできるのは、lpOverlapped パラメーターが NULL でない場合のみです。

lpFlagsDWORD*inoutWSARecv 関数呼び出しの動作を変更するために使用するフラグへのポインタ。詳細については「解説」のセクションを参照してください。
lpOverlappedOVERLAPPED*inoutoptionalWSAOVERLAPPED 構造体へのポインタ(非オーバーラップソケットでは無視されます)。
lpCompletionRoutineLPWSAOVERLAPPED_COMPLETION_ROUTINEinoptional受信操作が完了したときに呼び出される完了ルーチンへのポインタ(非オーバーラップソケットでは無視されます)。

戻り値の型: INT

公式ドキュメント

接続済みソケット、またはバインド済みのコネクションレスソケットからデータを受信します。(WSARecv)

戻り値

エラーが発生せず、受信操作がただちに完了した場合、 WSARecv はゼロを返します。この場合、呼び出し側スレッドがアラート可能状態(alertable state)になった時点で完了ルーチンが呼び出されるよう、すでにスケジュールされています。それ以外の場合は SOCKET_ERROR が返され、 WSAGetLastError を呼び出すことで具体的なエラーコードを取得できます。エラーコード WSA_IO_PENDING は、オーバーラップ操作が正常に開始され、完了は後で通知されることを示します。それ以外のエラーコードは、オーバーラップ操作が正常に開始されず、完了通知が発生しないことを示します。

エラーコード 意味
WSAECONNABORTED
タイムアウトまたはその他の障害により、仮想回線が終了しました。
WSAECONNRESET
ストリームソケットの場合、リモート側によって仮想回線がリセットされました。このソケットは使用できなくなるため、アプリケーションはソケットを閉じる必要があります。UDP データグラムソケットの場合、このエラーは、以前の送信操作によって ICMP の「Port Unreachable(ポート到達不能)」メッセージが返されたことを示します。
WSAEDISCON
ソケット s はメッセージ指向であり、仮想回線がリモート側によって正常に閉じられました。
WSAEFAULT
lpBuffers パラメーターが、ユーザーアドレス空間の有効な部分に完全には収まっていません。
WSAEINPROGRESS
ブロッキングを伴う Windows Sockets 1.1 の呼び出しが進行中であるか、サービスプロバイダーがコールバック関数を処理中です。
WSAEINTR
(ブロッキングを伴う)呼び出しが WSACancelBlockingCall 関数によってキャンセルされました。
WSAEINVAL
ソケットが(たとえば bind で)バインドされていません。
WSAEMSGSIZE
メッセージが大きすぎて指定されたバッファに収まらず、(信頼性のないプロトコルの場合のみ)バッファに収まらなかったメッセージの末尾部分は破棄されました。
WSAENETDOWN
ネットワークサブシステムに障害が発生しました。
WSAENETRESET
コネクション指向ソケットの場合、このエラーは、操作の進行中に障害を検出した keep-alive 動作によって接続が切断されたことを示します。データグラムソケットの場合、このエラーは存続時間(time to live)が経過したことを示します。
WSAENOTCONN
ソケットが接続されていません。
WSAENOTSOCK
ディスクリプタがソケットではありません。
WSAEOPNOTSUPP
MSG_OOB が指定されましたが、ソケットが SOCK_STREAM 型のようなストリーム形式ではない、OOB データがこのソケットに関連付けられた通信ドメインでサポートされていない、またはソケットが単方向で送信操作のみをサポートしています。
WSAESHUTDOWN
ソケットがシャットダウンされています。howSD_RECEIVE または SD_BOTH を指定して shutdown を呼び出した後は、そのソケットに対して WSARecv を呼び出すことはできません。
WSAETIMEDOUT
ネットワーク障害が発生したか、ピアシステムが応答しなかったため、接続が切断されました。
WSAEWOULDBLOCK

Windows NT: オーバーラップソケットの場合: 未完了のオーバーラップ I/O 要求が多すぎます。非オーバーラップソケットの場合: ソケットが非ブロッキングとしてマークされており、受信操作をただちに完了できません。

WSANOTINITIALISED
この関数を使用する前に、 WSAStartup の呼び出しが成功している必要があります。
WSA_IO_PENDING
オーバーラップ操作が正常に開始され、完了は後で通知されます。
WSA_OPERATION_ABORTED
ソケットが閉じられたため、オーバーラップ操作がキャンセルされました。

解説(Remarks)

WSARecv 関数は、標準の recv 関数と比べて、次の 3 つの重要な点で追加機能を提供します。

WSARecv 関数は、s パラメーターで指定された接続済みソケットまたはバインド済みのコネクションレスソケットに対して使用し、受信データを読み取るために使用します。ソケットのローカルアドレスが既知である必要があります。サーバーアプリケーションでは、通常これは bind によって明示的に行うか、 accept または WSAAccept によって暗黙的に行われます。クライアントアプリケーションでは明示的なバインドは推奨されません。クライアントアプリケーションでは、 connectWSAConnectsendtoWSASendTo、または WSAJoinLeaf を通じて、ソケットがローカルアドレスに暗黙的にバインドされます。

接続済みのコネクションレスソケットの場合、この関数は受信メッセージを受け付けるアドレスを制限します。接続で指定されたリモートアドレスからのメッセージのみを返します。他のアドレスからのメッセージは(暗黙のうちに)破棄されます。

オーバーラップソケットの場合、 WSARecv は、受信データが利用可能になり次第格納するための 1 つ以上のバッファを投入するために使用され、その後、アプリケーションが指定した完了通知(完了ルーチンの呼び出しまたはイベントオブジェクトのシグナル状態への設定)が発生します。操作がただちに完了しない場合、最終的な完了状態は完了ルーチンまたは WSAGetOverlappedResult を通じて取得します。

注意 あるスレッドによって開始されたすべての I/O は、そのスレッドが終了すると取り消されます。オーバーラップソケットの場合、操作が完了する前にスレッドが閉じられると、保留中の非同期操作が失敗することがあります。詳細については ExitThread を参照してください。
lpOverlappedlpCompletionRoutine の両方が NULL の場合、この関数内のソケットは非オーバーラップソケットとして扱われます。

非オーバーラップソケットの場合、ブロッキングのセマンティクスは標準の recv 関数と同一であり、lpOverlapped および lpCompletionRoutine パラメーターは無視されます。トランスポートによってすでに受信・バッファリングされているデータは、指定されたユーザーバッファにコピーされます。ブロッキングソケットで、トランスポートによって現在受信・バッファリングされているデータがない場合、呼び出しはデータが受信されるまでブロックします。Windows Sockets 2 は、この関数に対する標準的なブロッキングタイムアウト機構を定義していません。バイトストリームプロトコルとして動作するプロトコルの場合、スタックは利用可能なバッファ領域と受信済みデータ量に応じて、可能な限り多くのデータを返そうとします。ただし、1 バイトでも受信すれば呼び出し側のブロックを解除するのに十分です。1 バイトを超えるデータが返される保証はありません。メッセージ指向として動作するプロトコルの場合、呼び出し側のブロックを解除するには完全なメッセージが必要です。

注意 ソケットオプション SO_RCVTIMEO および SO_SNDTIMEO は、ブロッキングソケットにのみ適用されます。
プロトコルがバイトストリームとして動作するかどうかは、その WSAPROTOCOL_INFO 構造体における XP1_MESSAGE_ORIENTEDXP1_PSEUDO_STREAM の設定、およびこの関数に渡される MSG_PARTIAL フラグの設定(対応プロトコルの場合)によって決まります。次の表に関連する組み合わせを示します(アスタリスク (*) は、その場合にこのビットの設定が問題にならないことを示します)。
XP1_MESSAGE_ORIENTED XP1_PSEUDO_STREAM MSG_PARTIAL 動作
未設定 * * バイトストリーム
* 設定 * バイトストリーム
設定 未設定 設定 バイトストリーム
設定 未設定 未設定 メッセージ指向

バッファは、lpBuffers が指す配列に現れる順序で埋められ、間に隙間が生じないように詰めて格納されます。

この関数がオーバーラップ方式で完了する場合、この呼び出しから戻る前に WSABUF 構造体を取り込むのは Winsock サービスプロバイダーの責任です。これにより、アプリケーションは lpBuffers パラメーターが指すスタックベースの WSABUF 配列を構築できます。

バイトストリーム形式のソケット(たとえば SOCK_STREAM 型)の場合、受信データは、バッファが満たされるか、接続が閉じられるか、内部でバッファリングされたデータがなくなるまで、バッファに格納されます。受信データがすべてのバッファを満たすかどうかにかかわらず、オーバーラップソケットでは完了通知が発生します。

メッセージ指向ソケット(たとえば SOCK_DGRAM 型)の場合、受信メッセージはバッファの合計サイズまでバッファに格納され、オーバーラップソケットでは完了通知が発生します。メッセージがバッファより大きい場合、バッファにはメッセージの先頭部分が格納されます。基盤となるサービスプロバイダーが MSG_PARTIAL 機能をサポートしている場合、lpFlagsMSG_PARTIAL フラグが設定され、後続の受信操作でメッセージの残りが取得されます。MSG_PARTIAL がサポートされていないがプロトコルが信頼性のあるものである場合、 WSARecv はエラー WSAEMSGSIZE を生成し、より大きなバッファを指定した後続の受信操作でメッセージ全体を取得できます。それ以外の場合(つまり、プロトコルが信頼性がなく MSG_PARTIAL をサポートしていない場合)、超過分のデータは失われ、 WSARecv はエラー WSAEMSGSIZE を生成します。

コネクション指向ソケットの場合、 WSARecv は、ソケットがバイトストリームかメッセージ指向かに応じて、2 つの方法のいずれかで仮想回線の正常終了を通知できます。バイトストリームの場合、0 バイトが読み取られたこと(成功を示すゼロの戻り値と、lpNumberOfBytesRecvd の値がゼロであることで示されます)が、正常終了とそれ以上バイトが読み取られないことを示します。0 バイトメッセージがしばしば許容されるメッセージ指向ソケットの場合、エラーコード WSAEDISCON による失敗が正常終了を示すために使用されます。いずれの場合も、戻りエラーコード WSAECONNRESET は、強制的なクローズが発生したことを示します。

lpFlags パラメーターは、関連付けられたソケットに対して指定されたオプションを超えて、関数呼び出しの動作に影響を与えるために使用できます。つまり、この関数のセマンティクスは、ソケットオプションと lpFlags パラメーターによって決まります。後者は、次の表に示す値のいずれかをビット単位の OR 演算子で組み合わせて構築します。

意味
MSG_PEEK 受信データを覗き見します。データはバッファにコピーされますが、入力キューからは削除されません。

このフラグは非オーバーラップソケットでのみ有効です。

MSG_OOB OOB データを処理します。
MSG_PARTIAL このフラグはメッセージ指向ソケット専用です。出力時には、このフラグは指定されたデータが送信側によって送信されたメッセージの一部であることを示します。メッセージの残りの部分は後続の受信操作で指定されます。MSG_PARTIAL フラグがクリアされた後続の受信操作は、送信側メッセージの終端を示します。

入力パラメーターとして、このフラグは、トランスポートプロバイダーがメッセージの一部のみを受信した場合でも受信操作を完了すべきであることを示します。

MSG_PUSH_IMMEDIATE このフラグはストリーム指向ソケット専用です。このフラグにより、ストリームソケットを使用するアプリケーションは、部分的に満たされた保留中の受信要求の完了を遅延させないようトランスポートプロバイダーに指示できます。これは、まだ転送中の可能性のある残りのデータを必ずしも待たずに、できるだけ早く受信データを受け取りたいというアプリケーションの意図をトランスポートプロバイダーに伝えるヒントです。何をもって部分的に満たされた保留中の受信要求とみなすかは、トランスポート固有の事項です。

TCP の場合、これは、受信した TCP セグメントが受信要求のデータバッファに格納されており、どの TCP セグメントも PUSH ビットの値が 1 を示していなかった場合を指します。この場合、TCP は、PUSH ビットが 1 に設定された TCP セグメントとともに残りのデータが到着するのを待つために、部分的に満たされた受信要求をもう少し長く保持することがあります。このフラグは、受信要求を保持せずただちに完了するよう TCP に指示します。

部分ブロックの処理は最適でないことが多いため、大きなブロック転送にこのフラグを使用することは推奨されません。このフラグは、部分データをただちに受信・処理することが処理レイテンシの低減に役立つ場合にのみ有用です。

このフラグは実際の保証ではなくヒントです。

このフラグは Windows 8.1、Windows Server 2012 R2 以降でサポートされています。

MSG_WAITALL 受信要求は、次のいずれかのイベントが発生した場合にのみ完了します。
  • 呼び出し側が指定したバッファが完全に満たされた。
  • 接続が閉じられた。
  • 要求がキャンセルされた、またはエラーが発生した。

基盤となるトランスポートプロバイダーが MSG_WAITALL をサポートしていない場合、またはソケットが非ブロッキングモードである場合、この呼び出しは WSAEOPNOTSUPP で失敗することに注意してください。また、MSG_WAITALLMSG_OOBMSG_PEEK、または MSG_PARTIAL とともに指定された場合も、この呼び出しは WSAEOPNOTSUPP で失敗します。

このフラグはデータグラムソケットおよびメッセージ指向ソケットではサポートされていません。

メッセージ指向ソケットの場合、部分メッセージを受信すると lpFlags パラメーターに MSG_PARTIAL ビットが設定されます。完全なメッセージを受信すると、lpFlagsMSG_PARTIAL はクリアされます。完了が遅延する場合、lpFlags が指す値は更新されません。完了が通知されたら、アプリケーションは WSAGetOverlappedResult を呼び出し、lpdwFlags パラメーターで示されるフラグを確認する必要があります。

注意 lpOverlapped パラメーターを NULL に設定して WSARecv のようなブロッキングを伴う Winsock 呼び出しを発行する場合、呼び出しが完了する前に Winsock がネットワークイベントを待つ必要が生じることがあります。この状況で Winsock はアラート可能な待機を実行しますが、これは同じスレッドでスケジュールされた非同期プロシージャ呼び出し(APC)によって中断されることがあります。同じスレッドで進行中のブロッキング Winsock 呼び出しを中断した APC 内で別のブロッキング Winsock 呼び出しを発行すると、未定義の動作になるため、Winsock クライアントは決してこれを試みてはなりません。

オーバーラップソケット I/O

オーバーラップ操作がただちに完了した場合、 WSARecv はゼロを返し、lpNumberOfBytesRecvd パラメーターは受信したバイト数で更新され、lpFlags パラメーターで示されるフラグビットも更新されます。オーバーラップ操作が正常に開始され後で完了する場合、 WSARecvSOCKET_ERROR を返し、エラーコード WSA_IO_PENDING を示します。この場合、lpNumberOfBytesRecvdlpFlags は更新されません。オーバーラップ操作が完了すると、転送されたデータ量は、完了ルーチンの cbTransferred パラメーター(指定されている場合)を通じて、または WSAGetOverlappedResultlpcbTransfer パラメーターを通じて示されます。フラグ値は WSAGetOverlappedResultlpdwFlags パラメーターを調べることで取得されます。

オーバーラップ I/O を使用する WSARecv 関数は、直前の WSARecvWSARecvFromWSASend、または WSASendTo 関数の完了ルーチン内から呼び出すことができます。所定のソケットについて、I/O 完了ルーチンが入れ子になることはありません。これにより、時間に敏感なデータ送信を、完全にプリエンプティブなコンテキスト内で行うことができます。

lpOverlapped パラメーターは、オーバーラップ操作の継続中、有効である必要があります。複数の I/O 操作が同時に未完了である場合、それぞれが別個の WSAOVERLAPPED 構造体を参照する必要があります。

lpCompletionRoutine パラメーターが NULL の場合、lpOverlappedhEvent パラメーターが有効なイベントオブジェクトハンドルを含んでいれば、オーバーラップ操作の完了時にそれがシグナル状態になります。アプリケーションは WSAWaitForMultipleEvents または WSAGetOverlappedResult を使用して、イベントオブジェクトを待機またはポーリングできます。

lpCompletionRoutineNULL でない場合、hEvent パラメーターは無視され、アプリケーションが完了ルーチンにコンテキスト情報を渡すために使用できます。NULL でない lpCompletionRoutine を渡し、後で同じオーバーラップ I/O 要求に対して WSAGetOverlappedResult を呼び出す場合、その WSAGetOverlappedResult 呼び出しで fWait パラメーターを TRUE に設定してはなりません。この場合、hEvent パラメーターの使用は未定義であり、hEvent パラメーターを待機しようとすると予測不能な結果が生じます。

完了ルーチンは、Windows のファイル I/O 完了ルーチンに規定されているのと同じ規則に従います。完了ルーチンは、fAlertable パラメーターを TRUE に設定して WSAWaitForMultipleEvents 関数が呼び出された場合などに発生する、スレッドがアラート可能な待機状態になるまで呼び出されません。

完了ルーチンのプロトタイプは次のとおりです。


void CALLBACK CompletionROUTINE(
  IN DWORD dwError, 
  IN DWORD cbTransferred, 
  IN LPWSAOVERLAPPED lpOverlapped, 
  IN DWORD dwFlags
);

CompletionRoutine は、アプリケーション定義またはライブラリ定義の関数名のプレースホルダーです。dwError は、lpOverlapped で示されるオーバーラップ操作の完了状態を指定します。cbTransferred パラメーターは、受信したバイト数を指定します。dwFlags パラメーターには、受信操作がただちに完了していた場合に lpFlags に現れたであろう情報が含まれます。この関数は値を返しません。

この関数から戻ると、このソケットに対する別の保留中の完了ルーチンを呼び出すことができます。 WSAWaitForMultipleEvents を使用する場合、待機中のすべての完了ルーチンは、アラート可能なスレッドの待機が戻りコード WSA_IO_COMPLETION で満たされる前に呼び出されます。完了ルーチンは任意の順序で呼び出される可能性があり、必ずしもオーバーラップ操作が完了した順序と同じとは限りません。ただし、投入されたバッファは、指定された順序と同じ順序で埋められることが保証されます。

I/O 完了ポートを使用する場合、WSARecv を呼び出した順序がバッファに格納される順序でもあることに注意してください。予測不能なバッファ順序になる可能性があるため、WSARecv を異なるスレッドから同じソケットに対して同時に呼び出してはなりません。

サンプルコード

次の例は、オーバーラップ I/O モードで WSARecv 関数を使用する方法を示しています。
#ifndef UNICODE
#define UNICODE
#endif

#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif

#include <Windows.h>

#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#include <stdlib.h>

// Need to link with Ws2_32.lib
#pragma comment(lib, "ws2_32.lib")

#pragma warning(disable: 4127)  // Conditional expression is a constant

#define DATA_BUFSIZE 4096

int __cdecl main(int argc, char **argv)
{
    WSADATA wsd;
    struct addrinfo *result = NULL, *ptr = NULL, hints;
    WSAOVERLAPPED RecvOverlapped;
    SOCKET ConnSocket = INVALID_SOCKET;
    WSABUF DataBuf;
    DWORD RecvBytes, Flags;
    char buffer[DATA_BUFSIZE];

    int err = 0;
    int rc;

    if (argc != 2) {
        wprintf(L"usage: %s server-name\n", argv[0]);
        return 1;
    }
    // Load Winsock
    rc = WSAStartup(MAKEWORD(2, 2), &wsd);
    if (rc != 0) {
        wprintf(L"Unable to load Winsock: %d\n", rc);
        return 1;
    }
    // Make sure the hints struct is zeroed out
    SecureZeroMemory((PVOID) & hints, sizeof (struct addrinfo));

    // Initialize the hints to retrieve the server address for IPv4
    hints.ai_family = AF_INET;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP;

    rc = getaddrinfo(argv[1], "27015", &hints, &result);
    if (rc != 0) {
        wprintf(L"getaddrinfo failed with error: %d\n", rc);
        return 1;
    }

    for (ptr = result; ptr != NULL; ptr = ptr->ai_next) {

        ConnSocket = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
        if (ConnSocket == INVALID_SOCKET) {
            wprintf(L"socket failed with error: %d\n", WSAGetLastError());
            freeaddrinfo(result);
            return 1;
        }

        rc = connect(ConnSocket, ptr->ai_addr, (int) ptr->ai_addrlen);
        if (rc == SOCKET_ERROR) {

            if (WSAECONNREFUSED == (err = WSAGetLastError())) {
                closesocket(ConnSocket);
                ConnSocket = INVALID_SOCKET;
                continue;
            }
            wprintf(L"connect failed with error: %d\n", err);
            freeaddrinfo(result);
            closesocket(ConnSocket);
            return 1;
        }
        break;
    }
    if (ConnSocket == INVALID_SOCKET) {
        wprintf(L"Unable to establish connection with the server!\n");
        freeaddrinfo(result);
        return 1;
    }

    wprintf(L"Client connected...\n");

    // Make sure the RecvOverlapped struct is zeroed out
    SecureZeroMemory((PVOID) & RecvOverlapped, sizeof (WSAOVERLAPPED));

    // Create an event handle and setup an overlapped structure.
    RecvOverlapped.hEvent = WSACreateEvent();
    if (RecvOverlapped.hEvent == NULL) {
        wprintf(L"WSACreateEvent failed: %d\n", WSAGetLastError());
        freeaddrinfo(result);
        closesocket(ConnSocket);
        return 1;
    }

    DataBuf.len = DATA_BUFSIZE;
    DataBuf.buf = buffer;

    // Call WSARecv until the peer closes the connection
    // or until an error occurs
    while (1) {

        Flags = 0;
        rc = WSARecv(ConnSocket, &DataBuf, 1, &RecvBytes, &Flags, &RecvOverlapped, NULL);
        if ((rc == SOCKET_ERROR) && (WSA_IO_PENDING != (err = WSAGetLastError()))) {
            wprintf(L"WSARecv failed with error: %d\n", err);
            break;
        }

        rc = WSAWaitForMultipleEvents(1, &RecvOverlapped.hEvent, TRUE, INFINITE, TRUE);
        if (rc == WSA_WAIT_FAILED) {
            wprintf(L"WSAWaitForMultipleEvents failed with error: %d\n", WSAGetLastError());
            break;
        }

        rc = WSAGetOverlappedResult(ConnSocket, &RecvOverlapped, &RecvBytes, FALSE, &Flags);
        if (rc == FALSE) {
            wprintf(L"WSARecv operation failed with error: %d\n", WSAGetLastError());
            break;
        }

        wprintf(L"Read %d bytes\n", RecvBytes);

        WSAResetEvent(RecvOverlapped.hEvent);

        // If 0 bytes are received, the connection was closed
        if (RecvBytes == 0)
            break;
    }

    WSACloseEvent(RecvOverlapped.hEvent);
    closesocket(ConnSocket);
    freeaddrinfo(result);

    WSACleanup();

    return 0;
}

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 WSARecv(
    SOCKET s,
    WSABUF* lpBuffers,
    DWORD dwBufferCount,
    DWORD* lpNumberOfBytesRecvd,   // optional
    DWORD* lpFlags,
    OVERLAPPED* lpOverlapped,   // optional
    LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine   // optional
);
[DllImport("WS2_32.dll", SetLastError = true, ExactSpelling = true)]
static extern int WSARecv(
    UIntPtr s,   // SOCKET
    IntPtr lpBuffers,   // WSABUF*
    uint dwBufferCount,   // DWORD
    IntPtr lpNumberOfBytesRecvd,   // DWORD* optional, out
    ref uint lpFlags,   // DWORD* in/out
    IntPtr lpOverlapped,   // OVERLAPPED* optional, in/out
    IntPtr lpCompletionRoutine   // LPWSAOVERLAPPED_COMPLETION_ROUTINE optional
);
<DllImport("WS2_32.dll", SetLastError:=True, ExactSpelling:=True)>
Public Shared Function WSARecv(
    s As UIntPtr,   ' SOCKET
    lpBuffers As IntPtr,   ' WSABUF*
    dwBufferCount As UInteger,   ' DWORD
    lpNumberOfBytesRecvd As IntPtr,   ' DWORD* optional, out
    ByRef lpFlags As UInteger,   ' DWORD* in/out
    lpOverlapped As IntPtr,   ' OVERLAPPED* optional, in/out
    lpCompletionRoutine As IntPtr   ' LPWSAOVERLAPPED_COMPLETION_ROUTINE optional
) As Integer
End Function
' s : SOCKET
' lpBuffers : WSABUF*
' dwBufferCount : DWORD
' lpNumberOfBytesRecvd : DWORD* optional, out
' lpFlags : DWORD* in/out
' lpOverlapped : OVERLAPPED* optional, in/out
' lpCompletionRoutine : LPWSAOVERLAPPED_COMPLETION_ROUTINE optional
Declare PtrSafe Function WSARecv Lib "ws2_32" ( _
    ByVal s As LongPtr, _
    ByVal lpBuffers As LongPtr, _
    ByVal dwBufferCount As Long, _
    ByVal lpNumberOfBytesRecvd As LongPtr, _
    ByRef lpFlags As Long, _
    ByVal lpOverlapped As LongPtr, _
    ByVal lpCompletionRoutine As LongPtr) As Long
' VBA7前提(PtrSafe)。32bit Office では LongPtr→Long。Integer=16bit / Long=32bit / LongLong=64bit。
import ctypes
from ctypes import wintypes

WSARecv = ctypes.windll.ws2_32.WSARecv
WSARecv.restype = ctypes.c_int
WSARecv.argtypes = [
    ctypes.c_size_t,  # s : SOCKET
    ctypes.c_void_p,  # lpBuffers : WSABUF*
    wintypes.DWORD,  # dwBufferCount : DWORD
    ctypes.POINTER(wintypes.DWORD),  # lpNumberOfBytesRecvd : DWORD* optional, out
    ctypes.POINTER(wintypes.DWORD),  # lpFlags : DWORD* in/out
    ctypes.c_void_p,  # lpOverlapped : OVERLAPPED* optional, in/out
    ctypes.c_void_p,  # lpCompletionRoutine : LPWSAOVERLAPPED_COMPLETION_ROUTINE optional
]
# GetLastError: use ctypes.GetLastError() (or ctypes.WinDLL(use_last_error=True))
require 'fiddle'
require 'fiddle/import'

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

var (
	ws2_32 = windows.NewLazySystemDLL("WS2_32.dll")
	procWSARecv = ws2_32.NewProc("WSARecv")
)

// s (SOCKET), lpBuffers (WSABUF*), dwBufferCount (DWORD), lpNumberOfBytesRecvd (DWORD* optional, out), lpFlags (DWORD* in/out), lpOverlapped (OVERLAPPED* optional, in/out), lpCompletionRoutine (LPWSAOVERLAPPED_COMPLETION_ROUTINE optional)
r1, _, err := procWSARecv.Call(
	uintptr(s),
	uintptr(lpBuffers),
	uintptr(dwBufferCount),
	uintptr(lpNumberOfBytesRecvd),
	uintptr(lpFlags),
	uintptr(lpOverlapped),
	uintptr(lpCompletionRoutine),
)
_ = err  // syscall.Errno (valid when the call sets last-error)
_ = r1   // INT
function WSARecv(
  s: NativeUInt;   // SOCKET
  lpBuffers: Pointer;   // WSABUF*
  dwBufferCount: DWORD;   // DWORD
  lpNumberOfBytesRecvd: Pointer;   // DWORD* optional, out
  lpFlags: Pointer;   // DWORD* in/out
  lpOverlapped: Pointer;   // OVERLAPPED* optional, in/out
  lpCompletionRoutine: Pointer   // LPWSAOVERLAPPED_COMPLETION_ROUTINE optional
): Integer; stdcall;
  external 'WS2_32.dll' name 'WSARecv';
result := DllCall("WS2_32\WSARecv"
    , "UPtr", s   ; SOCKET
    , "Ptr", lpBuffers   ; WSABUF*
    , "UInt", dwBufferCount   ; DWORD
    , "Ptr", lpNumberOfBytesRecvd   ; DWORD* optional, out
    , "Ptr", lpFlags   ; DWORD* in/out
    , "Ptr", lpOverlapped   ; OVERLAPPED* optional, in/out
    , "Ptr", lpCompletionRoutine   ; LPWSAOVERLAPPED_COMPLETION_ROUTINE optional
    , "Int")   ; return: INT
●WSARecv(s, lpBuffers, dwBufferCount, lpNumberOfBytesRecvd, lpFlags, lpOverlapped, lpCompletionRoutine) = DLL("WS2_32.dll", "int WSARecv(int, void*, dword, void*, void*, void*, void*)")
# 呼び出し: WSARecv(s, lpBuffers, dwBufferCount, lpNumberOfBytesRecvd, lpFlags, lpOverlapped, lpCompletionRoutine)
# s : SOCKET -> "int"
# lpBuffers : WSABUF* -> "void*"
# dwBufferCount : DWORD -> "dword"
# lpNumberOfBytesRecvd : DWORD* optional, out -> "void*"
# lpFlags : DWORD* in/out -> "void*"
# lpOverlapped : OVERLAPPED* optional, in/out -> "void*"
# lpCompletionRoutine : LPWSAOVERLAPPED_COMPLETION_ROUTINE optional -> "void*"
# なでしこ1は32bit・ANSI(Shift_JIS)。文字列=char*(ANSI)、ポインタ/ハンドル=void*(4byte)。
const std = @import("std");

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

typedef WSARecvNative = Int32 Function(UintPtr, Pointer<Void>, Uint32, Pointer<Uint32>, Pointer<Uint32>, Pointer<Void>, Pointer<Void>);
typedef WSARecvDart = int Function(int, Pointer<Void>, int, Pointer<Uint32>, Pointer<Uint32>, Pointer<Void>, Pointer<Void>);
final WSARecv = DynamicLibrary.open('WS2_32.dll')
    .lookupFunction<WSARecvNative, WSARecvDart>('WSARecv');
// s : SOCKET -> UintPtr
// lpBuffers : WSABUF* -> Pointer<Void>
// dwBufferCount : DWORD -> Uint32
// lpNumberOfBytesRecvd : DWORD* optional, out -> Pointer<Uint32>
// lpFlags : DWORD* in/out -> Pointer<Uint32>
// lpOverlapped : OVERLAPPED* optional, in/out -> Pointer<Void>
// lpCompletionRoutine : LPWSAOVERLAPPED_COMPLETION_ROUTINE optional -> Pointer<Void>
// 文字列は package:ffi の "...".toNativeUtf16()/toNativeUtf8() で変換。
{$mode objfpc}{$H+}
function WSARecv(
  s: NativeUInt;   // SOCKET
  lpBuffers: Pointer;   // WSABUF*
  dwBufferCount: DWORD;   // DWORD
  lpNumberOfBytesRecvd: Pointer;   // DWORD* optional, out
  lpFlags: Pointer;   // DWORD* in/out
  lpOverlapped: Pointer;   // OVERLAPPED* optional, in/out
  lpCompletionRoutine: Pointer   // LPWSAOVERLAPPED_COMPLETION_ROUTINE optional
): Integer; stdcall;
  external 'WS2_32.dll' name 'WSARecv';
import Foreign
import Foreign.C.Types
import Foreign.C.String

foreign import stdcall safe "WSARecv"
  c_WSARecv :: CUIntPtr -> Ptr () -> Word32 -> Ptr Word32 -> Ptr Word32 -> Ptr () -> Ptr () -> IO Int32
-- s : SOCKET -> CUIntPtr
-- lpBuffers : WSABUF* -> Ptr ()
-- dwBufferCount : DWORD -> Word32
-- lpNumberOfBytesRecvd : DWORD* optional, out -> Ptr Word32
-- lpFlags : DWORD* in/out -> Ptr Word32
-- lpOverlapped : OVERLAPPED* optional, in/out -> Ptr ()
-- lpCompletionRoutine : LPWSAOVERLAPPED_COMPLETION_ROUTINE optional -> Ptr ()
-- 要 GHC(Windows)。stdcall は x64 では ccall として扱われる。ブロックする API は safe 呼び出し推奨。
open Ctypes
open Foreign

let wsarecv =
  foreign "WSARecv"
    (size_t @-> (ptr void) @-> uint32_t @-> (ptr uint32_t) @-> (ptr uint32_t) @-> (ptr void) @-> (ptr void) @-> returning int32_t)
(* s : SOCKET -> size_t *)
(* lpBuffers : WSABUF* -> (ptr void) *)
(* dwBufferCount : DWORD -> uint32_t *)
(* lpNumberOfBytesRecvd : DWORD* optional, out -> (ptr uint32_t) *)
(* lpFlags : DWORD* in/out -> (ptr uint32_t) *)
(* lpOverlapped : OVERLAPPED* optional, in/out -> (ptr void) *)
(* lpCompletionRoutine : LPWSAOVERLAPPED_COMPLETION_ROUTINE 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 ("WSARecv" wsarecv :convention :stdcall) :int32
  (s :uint64)   ; SOCKET
  (lp-buffers :pointer)   ; WSABUF*
  (dw-buffer-count :uint32)   ; DWORD
  (lp-number-of-bytes-recvd :pointer)   ; DWORD* optional, out
  (lp-flags :pointer)   ; DWORD* in/out
  (lp-overlapped :pointer)   ; OVERLAPPED* optional, in/out
  (lp-completion-routine :pointer))   ; LPWSAOVERLAPPED_COMPLETION_ROUTINE optional
; isize/usize(INT_PTR/SIZE_T)は x64 前提で :int64/:uint64。x86 では :int32/:uint32。
use Win32::API;
my $WSARecv = Win32::API::More->new('WS2_32',
    'int WSARecv(WPARAM s, LPVOID lpBuffers, DWORD dwBufferCount, LPVOID lpNumberOfBytesRecvd, LPVOID lpFlags, LPVOID lpOverlapped, LPVOID lpCompletionRoutine)');
# my $ret = $WSARecv->Call($s, $lpBuffers, $dwBufferCount, $lpNumberOfBytesRecvd, $lpFlags, $lpOverlapped, $lpCompletionRoutine);
# s : SOCKET -> WPARAM
# lpBuffers : WSABUF* -> LPVOID
# dwBufferCount : DWORD -> DWORD
# lpNumberOfBytesRecvd : DWORD* optional, out -> LPVOID
# lpFlags : DWORD* in/out -> LPVOID
# lpOverlapped : OVERLAPPED* optional, in/out -> LPVOID
# lpCompletionRoutine : LPWSAOVERLAPPED_COMPLETION_ROUTINE optional -> LPVOID
# 値渡し構造体は pack() した文字列、または Win32::API::Struct を使用。
# コールバック(関数ポインタ)は Perl sub を直接渡せません。Win32::API::Callback を使用してください。

関連項目

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