WSARecvFrom
関数シグネチャ
// WS2_32.dll
#include <windows.h>
INT WSARecvFrom(
SOCKET s,
WSABUF* lpBuffers,
DWORD dwBufferCount,
DWORD* lpNumberOfBytesRecvd, // optional
DWORD* lpFlags,
SOCKADDR* lpFrom, // optional
INT* lpFromlen, // optional
OVERLAPPED* lpOverlapped, // optional
LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine // optional
);パラメーター
| 名前 | 型 | 方向 | 説明 |
|---|---|---|---|
| s | SOCKET | in | socket を識別するディスクリプタ。 |
| lpBuffers | WSABUF* | in | WSABUF 構造体の配列へのポインタ。各 WSABUF 構造体には、バッファへのポインタとバッファの長さが含まれます。 |
| dwBufferCount | DWORD | in | lpBuffers 配列内の WSABUF 構造体の数。 |
| lpNumberOfBytesRecvd | DWORD* | outoptional | WSARecvFrom 操作が即座に完了した場合に、この呼び出しで受信したバイト数を格納するポインタ。 誤った結果が生じる可能性を避けるため、lpOverlapped パラメータが NULL でない場合は、このパラメータに NULL を使用してください。このパラメータを NULL にできるのは、lpOverlapped パラメータが NULL でない場合のみです。 |
| lpFlags | DWORD* | inout | WSARecvFrom 関数呼び出しの動作を変更するために使用するフラグへのポインタ。後述の解説を参照してください。 |
| lpFrom | SOCKADDR* | outoptional | オーバーラップ操作の完了時に送信元アドレスを保持するバッファへの、省略可能なポインタ。 |
| lpFromlen | INT* | inoutoptional | "from" バッファのサイズ(バイト単位)へのポインタ。lpFrom が指定されている場合にのみ必要です。 |
| lpOverlapped | OVERLAPPED* | inoutoptional | WSAOVERLAPPED 構造体へのポインタ(非オーバーラップソケットでは無視されます)。 |
| lpCompletionRoutine | LPWSAOVERLAPPED_COMPLETION_ROUTINE | inoptional | WSARecvFrom 操作が完了したときに呼び出される完了ルーチンへのポインタ(非オーバーラップソケットでは無視されます)。 |
戻り値の型: INT
公式ドキュメント
データグラムを受信し、送信元アドレスを格納します。
戻り値
エラーが発生せず、受信操作が即座に完了した場合、 WSARecvFrom はゼロを返します。この場合、呼び出し元スレッドがアラート可能状態になると、完了ルーチンが既に呼び出されるようスケジュールされています。それ以外の場合は SOCKET_ERROR が返され、 WSAGetLastError を呼び出すことで具体的なエラーコードを取得できます。エラーコード WSA_IO_PENDING は、オーバーラップ操作が正常に開始され、完了が後で通知されることを示します。それ以外のエラーコードは、オーバーラップ操作が正常に開始されず、完了通知が行われないことを示します。
| エラーコード | 意味 |
|---|---|
| リモート側がハードクローズまたはアボート的なクローズを実行したため、仮想回線がリセットされました。socket はもはや使用できないため、アプリケーションはこれをクローズする必要があります。UDP データグラムソケットの場合、このエラーは、以前の送信操作が ICMP の "Port Unreachable"(ポート到達不能)メッセージを引き起こしたことを示します。 | |
| lpBuffers、lpFlags、lpFrom、lpNumberOfBytesRecvd、lpFromlen、lpOverlapped、または lpCompletionRoutine パラメータが、ユーザーアドレス空間の有効な部分に完全には含まれていません。lpFrom バッファが、ピアアドレスを格納するには小さすぎました。 | |
| ブロッキング型の Windows Sockets 1.1 呼び出しが進行中であるか、サービスプロバイダーがコールバック関数をまだ処理しています。 | |
| ブロッキング型の Windows Socket 1.1 呼び出しが WSACancelBlockingCall によってキャンセルされました。 | |
| socket が(たとえば bind によって)バインドされていません。 | |
| メッセージが指定されたバッファに対して大きすぎ、(信頼性のないプロトコルの場合のみ)バッファに収まらなかったメッセージの末尾部分は破棄されました。 | |
| ネットワークサブシステムが失敗しました。 | |
| データグラムソケットの場合、このエラーは TTL(time to live)が期限切れになったことを示します。 | |
| socket が接続されていません(コネクション指向ソケットのみ)。 | |
|
Windows NT:
オーバーラップソケット: 未処理のオーバーラップ I/O 要求が多すぎます。非オーバーラップソケット: socket は非ブロッキングとしてマークされており、受信操作を即座に完了できません。 |
|
| この関数を使用する前に、 WSAStartup の呼び出しが成功している必要があります。 | |
| オーバーラップ操作が正常に開始され、完了は後で通知されます。 | |
| socket のクローズにより、オーバーラップ操作がキャンセルされました。 |
解説(Remarks)
WSARecvFrom 関数は、標準の recvfrom 関数に加えて、次の3つの重要な点で機能を提供します。
- オーバーラップソケットと組み合わせて使用し、オーバーラップ受信操作を実行できます。
- 複数の受信バッファを指定できるため、スキャッタ/ギャザー型の I/O に適用できます。
- lpFlags パラメータは入力パラメータと出力パラメータの両方を兼ねており、アプリケーションは MSG_PARTIAL フラグビットの出力状態を検知できます。MSG_PARTIAL フラグビットはすべてのプロトコルでサポートされているわけではないことに注意してください。
WSARecvFrom 関数は、主に s で指定されたコネクションレスソケットで使用されます。socket のローカルアドレスが既知である必要があります。サーバーアプリケーションの場合、これは通常 bind によって明示的に行われます。クライアントアプリケーションでは、明示的なバインドは推奨されません。この関数を使用するクライアントアプリケーションでは、socket は sendto、 WSASendTo、または WSAJoinLeaf を通じて、ローカルアドレスに暗黙的にバインドされることがあります。
オーバーラップソケットの場合、この関数は、(場合によっては接続された)socket で受信データが利用可能になったときにそれを格納するための1つ以上のバッファをポストするために使用されます。その後、アプリケーションが指定した完了通知(完了ルーチンの呼び出し、またはイベントオブジェクトの設定)が行われます。操作が即座に完了しない場合、最終的な完了ステータスは、完了ルーチンまたは WSAGetOverlappedResult を通じて取得されます。また、lpFrom および lpFromlen が指す値は、完了自体が通知されるまで更新されません。アプリケーションはこれらの値が更新されるまで使用したり変更したりしてはなりません。したがって、これらのパラメータには自動変数(つまりスタックベースの変数)を使用してはなりません。
非オーバーラップソケットの場合、ブロッキングのセマンティクスは標準の WSARecv 関数と同一であり、lpOverlapped および lpCompletionRoutine パラメータは無視されます。トランスポートによって既に受信されバッファリングされたデータは、ユーザーバッファにコピーされます。ブロッキングソケットでトランスポートによって現在受信およびバッファリングされたデータがない場合、呼び出しはデータが受信されるまでブロックします。
バッファは、lpBuffers が示す配列に現れる順序で埋められ、隙間が生じないように詰めて格納されます。
この関数がオーバーラップ方式で完了する場合、この呼び出しから戻る前に WSABUF 構造体をキャプチャするのは Winsock サービスプロバイダーの責任です。これにより、アプリケーションは lpBuffers パラメータが指すスタックベースの WSABUF 配列を構築できます。
コネクションレスのソケット型の場合、データの送信元アドレスが lpFrom が示すバッファにコピーされます。lpFromlen が指す値は、このバッファのサイズに初期化され、完了時にそこに格納された実際のアドレスのサイズを示すように変更されます。前述のとおり、オーバーラップソケットの場合、lpFrom および lpFromlen パラメータは、オーバーラップ I/O が完了するまで更新されません。したがって、これらのパラメータが指すメモリはサービスプロバイダーが利用可能な状態を保つ必要があり、アプリケーションのスタックフレーム上に確保することはできません。コネクション指向ソケットの場合、lpFrom および lpFromlen パラメータは無視されます。
バイトストリーム型のソケット(たとえば SOCK_STREAM 型)の場合、受信データは次のいずれかになるまでバッファに格納されます。
- バッファが満杯になる。
- 接続がクローズされる。
- 内部的にバッファリングされたデータがなくなる。
lpFlags パラメータは、関連付けられた socket に指定されたオプションを超えて、関数呼び出しの動作に影響を与えるために使用できます。すなわち、この関数のセマンティクスは、ソケットオプションと lpFlags パラメータによって決定されます。後者は、次の表に示す値のいずれかをビット単位の OR 演算子で組み合わせて構築します。
| 値 | 意味 |
|---|---|
| MSG_PEEK | 受信データをプレビューします。データはバッファにコピーされますが、入力キューからは削除されません。このフラグは非オーバーラップソケットでのみ有効です。 |
| MSG_OOB | OOB データを処理します。 |
| MSG_PARTIAL | このフラグはメッセージ指向ソケットでのみ使用します。出力時には、このフラグは、データが送信側によって送信されたメッセージの一部であることを示します。メッセージの残りの部分は、後続の受信操作で送信されます。MSG_PARTIAL フラグがクリアされた後続の受信操作は、送信側のメッセージの終わりを示します。
入力パラメータとしては、このフラグは、メッセージの一部のみがサービスプロバイダーによって受信された場合でも受信操作を完了すべきであることを示します。 |
メッセージ指向ソケットの場合、部分的なメッセージを受信すると lpFlags パラメータに MSG_PARTIAL ビットが設定されます。完全なメッセージを受信した場合、lpFlags の MSG_PARTIAL はクリアされます。完了が遅延する場合、lpFlags が指す値は更新されません。完了が通知されたら、アプリケーションは WSAGetOverlappedResult を呼び出し、lpdwFlags パラメータが指すフラグを調べる必要があります。
オーバーラップソケット I/O
オーバーラップ操作が即座に完了した場合、 WSARecvFrom はゼロを返し、lpNumberOfBytesRecvd パラメータは受信したバイト数で更新され、lpFlags パラメータが指すフラグビットも更新されます。オーバーラップ操作が正常に開始され後で完了する場合、 WSARecvFrom は SOCKET_ERROR を返し、エラーコード WSA_IO_PENDING を示します。この場合、lpNumberOfBytesRecvd および lpFlags は更新されません。オーバーラップ操作が完了すると、転送されたデータ量は、(指定されている場合は)完了ルーチンの cbTransferred パラメータを通じて、または WSAGetOverlappedResult の lpcbTransfer パラメータを通じて示されます。フラグ値は、完了ルーチンの dwFlags パラメータを通じて、または WSAGetOverlappedResult の lpdwFlags パラメータを調べることで取得されます。WSARecvFrom 関数は、以前の WSARecv、 WSARecvFrom、 WSASend、または WSASendTo 関数の完了ルーチン内から呼び出すことができます。所与の socket について、I/O 完了ルーチンがネストされることはありません。これにより、時間的制約のあるデータ送信を、プリエンプティブなコンテキスト内で完結させることができます。
lpOverlapped パラメータは、オーバーラップ操作の期間中、有効である必要があります。複数の I/O 操作が同時に未処理である場合、それぞれが別個の WSAOVERLAPPED 構造体を参照する必要があります。
lpCompletionRoutine パラメータが NULL の場合、lpOverlapped の hEvent パラメータが有効なイベントオブジェクトハンドルを含んでいれば、オーバーラップ操作の完了時にそれがシグナル状態になります。アプリケーションは WSAWaitForMultipleEvents または WSAGetOverlappedResult を使用して、イベントオブジェクトを待機またはポーリングできます。
lpCompletionRoutine が NULL でない場合、hEvent パラメータは無視され、アプリケーションが完了ルーチンにコンテキスト情報を渡すために使用できます。NULL でない lpCompletionRoutine を渡し、後で同じオーバーラップ I/O 要求に対して WSAGetOverlappedResult を呼び出す呼び出し元は、その WSAGetOverlappedResult の呼び出しに対して fWait パラメータを TRUE に設定してはなりません。この場合、hEvent パラメータの使用法は未定義であり、hEvent パラメータの待機を試みると予測不能な結果を生じます。
完了ルーチンは、Windows のファイル I/O 完了ルーチンに規定されているのと同じ規則に従います。完了ルーチンは、fAlertable パラメータを TRUE に設定して WSAWaitForMultipleEvents 関数を呼び出した場合に生じうるような、スレッドがアラート可能な待機状態になるまで呼び出されません。
IO 完了ポートが使用され、lpCompletionRoutine パラメータと hEvent パラメータが NULL の場合、操作の結果は IO 完了ポートにスケジュールされます。これは、操作が即座に完了するかどうかにかかわらず、すべての成功した操作で発生します。
トランスポートプロバイダーは、アプリケーションが socket I/O 完了ルーチンのコンテキスト内から送信および受信操作を呼び出すことを許可し、所与の socket について I/O 完了ルーチンがネストされないことを保証します。これにより、時間的制約のあるデータ送信を、プリエンプティブなコンテキスト内で完結させることができます。
完了ルーチンのプロトタイプは次のとおりです。
void CALLBACK CompletionROUTINE(
IN DWORD dwError,
IN DWORD cbTransferred,
IN LPWSAOVERLAPPED lpOverlapped,
IN DWORD dwFlags
);
CompletionRoutine は、アプリケーション定義またはライブラリ定義の関数名のプレースホルダです。dwError は、lpOverlapped が示すオーバーラップ操作の完了ステータスを指定します。cbTransferred は、受信したバイト数を指定します。dwFlags パラメータには、受信操作が即座に完了した場合に lpFlags に現れたであろう情報が含まれます。この関数は値を返しません。
この関数から戻ると、この socket に対する別の保留中の完了ルーチンの呼び出しが可能になります。 WSAWaitForMultipleEvents を使用する場合、待機中のすべての完了ルーチンが呼び出された後で、アラート可能なスレッドの待機が WSA_IO_COMPLETION の戻りコードで満たされます。完了ルーチンは任意の順序で呼び出される可能性があり、必ずしもオーバーラップ操作が完了したのと同じ順序になるとは限りません。ただし、ポストされたバッファは、指定されたのと同じ順序で埋められることが保証されます。
サンプルコード
次の例は、WSARecvFrom 関数の使用方法を示しています。#ifndef UNICODE
#define UNICODE
#endif
#define WIN32_LEAN_AND_MEAN
#include <winsock2.h>
#include <Ws2tcpip.h>
#include <stdio.h>
int __cdecl main()
{
WSADATA wsaData;
WSABUF DataBuf;
WSAOVERLAPPED Overlapped;
SOCKET RecvSocket = INVALID_SOCKET;
struct sockaddr_in RecvAddr;
struct sockaddr_in SenderAddr;
int SenderAddrSize = sizeof (SenderAddr);
u_short Port = 27015;
char RecvBuf[1024];
int BufLen = 1024;
DWORD BytesRecv = 0;
DWORD Flags = 0;
int err = 0;
int rc;
int retval = 0;
//-----------------------------------------------
// Initialize Winsock
rc = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (rc != 0) {
/* Could not find a usable Winsock DLL */
wprintf(L"WSAStartup failed with error: %ld\n", rc);
return 1;
}
// Make sure the Overlapped struct is zeroed out
SecureZeroMemory((PVOID) &Overlapped, sizeof(WSAOVERLAPPED) );
// Create an event handle and setup the overlapped structure.
Overlapped.hEvent = WSACreateEvent();
if (Overlapped.hEvent == NULL) {
wprintf(L"WSACreateEvent failed with error: %d\n", WSAGetLastError());
WSACleanup();
return 1;
}
//-----------------------------------------------
// Create a receiver socket to receive datagrams
RecvSocket = WSASocket(AF_INET,
SOCK_DGRAM,
IPPROTO_UDP, NULL, 0, WSA_FLAG_OVERLAPPED);
if (RecvSocket == INVALID_SOCKET) {
/* Could not open a socket */
wprintf(L"WSASocket failed with error: %ld\n", WSAGetLastError());
WSACloseEvent(Overlapped.hEvent);
WSACleanup();
return 1;
}
//-----------------------------------------------
// Bind the socket to any address and the specified port.
RecvAddr.sin_family = AF_INET;
RecvAddr.sin_port = htons(Port);
RecvAddr.sin_addr.s_addr = htonl(INADDR_ANY);
rc = bind(RecvSocket, (SOCKADDR *) & RecvAddr, sizeof (RecvAddr));
if (rc != 0) {
/* Bind to the socket failed */
wprintf(L"bind failed with error: %ld\n", WSAGetLastError());
WSACloseEvent(Overlapped.hEvent);
closesocket(RecvSocket);
WSACleanup();
return 1;
}
//-----------------------------------------------
// Call the recvfrom function to receive datagrams
// on the bound socket.
DataBuf.len = BufLen;
DataBuf.buf = RecvBuf;
wprintf(L"Listening for incoming datagrams on port=%d\n", Port);
rc = WSARecvFrom(RecvSocket,
&DataBuf,
1,
&BytesRecv,
&Flags,
(SOCKADDR *) & SenderAddr,
&SenderAddrSize, &Overlapped, NULL);
if (rc != 0) {
err = WSAGetLastError();
if (err != WSA_IO_PENDING) {
wprintf(L"WSARecvFrom failed with error: %ld\n", err);
WSACloseEvent(Overlapped.hEvent);
closesocket(RecvSocket);
WSACleanup();
return 1;
}
else {
rc = WSAWaitForMultipleEvents(1, &Overlapped.hEvent, TRUE, INFINITE, TRUE);
if (rc == WSA_WAIT_FAILED) {
wprintf(L"WSAWaitForMultipleEvents failed with error: %d\n", WSAGetLastError());
retval = 1;
}
rc = WSAGetOverlappedResult(RecvSocket, &Overlapped, &BytesRecv,
FALSE, &Flags);
if (rc == FALSE) {
wprintf(L"WSArecvFrom failed with error: %d\n", WSAGetLastError());
retval = 1;
}
else
wprintf(L"Number of received bytes = %d\n", BytesRecv);
wprintf(L"Finished receiving. Closing socket.\n");
}
}
//---------------------------------------------
// When the application is finished receiving, close the socket.
WSACloseEvent(Overlapped.hEvent);
closesocket(RecvSocket);
wprintf(L"Exiting.\n");
//---------------------------------------------
// Clean up and quit.
WSACleanup();
return (retval);
}
Windows Phone 8: この関数は、Windows Phone 8 以降の Windows Phone ストアアプリでサポートされています。
Windows 8.1 および Windows Server 2012 R2: この関数は、Windows 8.1、Windows Server 2012 R2 以降の Windows ストアアプリでサポートされています。
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)
各言語での呼び出し定義
// WS2_32.dll
#include <windows.h>
INT WSARecvFrom(
SOCKET s,
WSABUF* lpBuffers,
DWORD dwBufferCount,
DWORD* lpNumberOfBytesRecvd, // optional
DWORD* lpFlags,
SOCKADDR* lpFrom, // optional
INT* lpFromlen, // optional
OVERLAPPED* lpOverlapped, // optional
LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine // optional
);[DllImport("WS2_32.dll", SetLastError = true, ExactSpelling = true)]
static extern int WSARecvFrom(
UIntPtr s, // SOCKET
IntPtr lpBuffers, // WSABUF*
uint dwBufferCount, // DWORD
IntPtr lpNumberOfBytesRecvd, // DWORD* optional, out
ref uint lpFlags, // DWORD* in/out
IntPtr lpFrom, // SOCKADDR* optional, out
IntPtr lpFromlen, // INT* optional, 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 WSARecvFrom(
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
lpFrom As IntPtr, ' SOCKADDR* optional, out
lpFromlen As IntPtr, ' INT* optional, 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
' lpFrom : SOCKADDR* optional, out
' lpFromlen : INT* optional, in/out
' lpOverlapped : OVERLAPPED* optional, in/out
' lpCompletionRoutine : LPWSAOVERLAPPED_COMPLETION_ROUTINE optional
Declare PtrSafe Function WSARecvFrom Lib "ws2_32" ( _
ByVal s As LongPtr, _
ByVal lpBuffers As LongPtr, _
ByVal dwBufferCount As Long, _
ByVal lpNumberOfBytesRecvd As LongPtr, _
ByRef lpFlags As Long, _
ByVal lpFrom As LongPtr, _
ByVal lpFromlen As LongPtr, _
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
WSARecvFrom = ctypes.windll.ws2_32.WSARecvFrom
WSARecvFrom.restype = ctypes.c_int
WSARecvFrom.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, # lpFrom : SOCKADDR* optional, out
ctypes.POINTER(ctypes.c_int), # lpFromlen : INT* optional, 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')
WSARecvFrom = Fiddle::Function.new(
lib['WSARecvFrom'],
[
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, # lpFrom : SOCKADDR* optional, out
Fiddle::TYPE_VOIDP, # lpFromlen : INT* optional, 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 WSARecvFrom(
s: usize, // SOCKET
lpBuffers: *mut WSABUF, // WSABUF*
dwBufferCount: u32, // DWORD
lpNumberOfBytesRecvd: *mut u32, // DWORD* optional, out
lpFlags: *mut u32, // DWORD* in/out
lpFrom: *mut SOCKADDR, // SOCKADDR* optional, out
lpFromlen: *mut i32, // INT* optional, 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 WSARecvFrom(UIntPtr s, IntPtr lpBuffers, uint dwBufferCount, IntPtr lpNumberOfBytesRecvd, ref uint lpFlags, IntPtr lpFrom, IntPtr lpFromlen, IntPtr lpOverlapped, IntPtr lpCompletionRoutine);
"@
$api = Add-Type -MemberDefinition $sig -Name 'WS2_32_WSARecvFrom' -Namespace Win32 -PassThru
# $api::WSARecvFrom(s, lpBuffers, dwBufferCount, lpNumberOfBytesRecvd, lpFlags, lpFrom, lpFromlen, lpOverlapped, lpCompletionRoutine)#uselib "WS2_32.dll"
#func global WSARecvFrom "WSARecvFrom" sptr, sptr, sptr, sptr, sptr, sptr, sptr, sptr, sptr
; WSARecvFrom s, varptr(lpBuffers), dwBufferCount, varptr(lpNumberOfBytesRecvd), varptr(lpFlags), varptr(lpFrom), varptr(lpFromlen), varptr(lpOverlapped), lpCompletionRoutine ; 戻り値は stat
; s : SOCKET -> "sptr"
; lpBuffers : WSABUF* -> "sptr"
; dwBufferCount : DWORD -> "sptr"
; lpNumberOfBytesRecvd : DWORD* optional, out -> "sptr"
; lpFlags : DWORD* in/out -> "sptr"
; lpFrom : SOCKADDR* optional, out -> "sptr"
; lpFromlen : INT* optional, 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 WSARecvFrom "WSARecvFrom" sptr, var, int, var, var, var, var, var, sptr ; res = WSARecvFrom(s, lpBuffers, dwBufferCount, lpNumberOfBytesRecvd, lpFlags, lpFrom, lpFromlen, lpOverlapped, lpCompletionRoutine) ; s : SOCKET -> "sptr" ; lpBuffers : WSABUF* -> "var" ; dwBufferCount : DWORD -> "int" ; lpNumberOfBytesRecvd : DWORD* optional, out -> "var" ; lpFlags : DWORD* in/out -> "var" ; lpFrom : SOCKADDR* optional, out -> "var" ; lpFromlen : INT* optional, in/out -> "var" ; lpOverlapped : OVERLAPPED* optional, in/out -> "var" ; lpCompletionRoutine : LPWSAOVERLAPPED_COMPLETION_ROUTINE optional -> "sptr" ; ※出力/バッファ引数は var 方式(変数を直接渡す)。varptr 方式にも切替可。#uselib "WS2_32.dll" #cfunc global WSARecvFrom "WSARecvFrom" sptr, sptr, int, sptr, sptr, sptr, sptr, sptr, sptr ; res = WSARecvFrom(s, varptr(lpBuffers), dwBufferCount, varptr(lpNumberOfBytesRecvd), varptr(lpFlags), varptr(lpFrom), varptr(lpFromlen), varptr(lpOverlapped), lpCompletionRoutine) ; s : SOCKET -> "sptr" ; lpBuffers : WSABUF* -> "sptr" ; dwBufferCount : DWORD -> "int" ; lpNumberOfBytesRecvd : DWORD* optional, out -> "sptr" ; lpFlags : DWORD* in/out -> "sptr" ; lpFrom : SOCKADDR* optional, out -> "sptr" ; lpFromlen : INT* optional, in/out -> "sptr" ; lpOverlapped : OVERLAPPED* optional, in/out -> "sptr" ; lpCompletionRoutine : LPWSAOVERLAPPED_COMPLETION_ROUTINE optional -> "sptr" ; ※出力/バッファ引数はポインタ方式(token=sptr / 呼び出しは varptr(変数))。
; INT WSARecvFrom(SOCKET s, WSABUF* lpBuffers, DWORD dwBufferCount, DWORD* lpNumberOfBytesRecvd, DWORD* lpFlags, SOCKADDR* lpFrom, INT* lpFromlen, OVERLAPPED* lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine) #uselib "WS2_32.dll" #cfunc global WSARecvFrom "WSARecvFrom" intptr, var, int, var, var, var, var, var, intptr ; res = WSARecvFrom(s, lpBuffers, dwBufferCount, lpNumberOfBytesRecvd, lpFlags, lpFrom, lpFromlen, lpOverlapped, lpCompletionRoutine) ; s : SOCKET -> "intptr" ; lpBuffers : WSABUF* -> "var" ; dwBufferCount : DWORD -> "int" ; lpNumberOfBytesRecvd : DWORD* optional, out -> "var" ; lpFlags : DWORD* in/out -> "var" ; lpFrom : SOCKADDR* optional, out -> "var" ; lpFromlen : INT* optional, in/out -> "var" ; lpOverlapped : OVERLAPPED* optional, in/out -> "var" ; lpCompletionRoutine : LPWSAOVERLAPPED_COMPLETION_ROUTINE optional -> "intptr" ; ※出力/バッファ引数は var 方式(変数を直接渡す)。varptr 方式にも切替可。; INT WSARecvFrom(SOCKET s, WSABUF* lpBuffers, DWORD dwBufferCount, DWORD* lpNumberOfBytesRecvd, DWORD* lpFlags, SOCKADDR* lpFrom, INT* lpFromlen, OVERLAPPED* lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine) #uselib "WS2_32.dll" #cfunc global WSARecvFrom "WSARecvFrom" intptr, intptr, int, intptr, intptr, intptr, intptr, intptr, intptr ; res = WSARecvFrom(s, varptr(lpBuffers), dwBufferCount, varptr(lpNumberOfBytesRecvd), varptr(lpFlags), varptr(lpFrom), varptr(lpFromlen), varptr(lpOverlapped), lpCompletionRoutine) ; s : SOCKET -> "intptr" ; lpBuffers : WSABUF* -> "intptr" ; dwBufferCount : DWORD -> "int" ; lpNumberOfBytesRecvd : DWORD* optional, out -> "intptr" ; lpFlags : DWORD* in/out -> "intptr" ; lpFrom : SOCKADDR* optional, out -> "intptr" ; lpFromlen : INT* optional, in/out -> "intptr" ; lpOverlapped : OVERLAPPED* optional, in/out -> "intptr" ; lpCompletionRoutine : LPWSAOVERLAPPED_COMPLETION_ROUTINE optional -> "intptr" ; ※出力/バッファ引数はポインタ方式(token=intptr / 呼び出しは varptr(変数))。
import (
"golang.org/x/sys/windows"
"unsafe"
)
var (
ws2_32 = windows.NewLazySystemDLL("WS2_32.dll")
procWSARecvFrom = ws2_32.NewProc("WSARecvFrom")
)
// s (SOCKET), lpBuffers (WSABUF*), dwBufferCount (DWORD), lpNumberOfBytesRecvd (DWORD* optional, out), lpFlags (DWORD* in/out), lpFrom (SOCKADDR* optional, out), lpFromlen (INT* optional, in/out), lpOverlapped (OVERLAPPED* optional, in/out), lpCompletionRoutine (LPWSAOVERLAPPED_COMPLETION_ROUTINE optional)
r1, _, err := procWSARecvFrom.Call(
uintptr(s),
uintptr(lpBuffers),
uintptr(dwBufferCount),
uintptr(lpNumberOfBytesRecvd),
uintptr(lpFlags),
uintptr(lpFrom),
uintptr(lpFromlen),
uintptr(lpOverlapped),
uintptr(lpCompletionRoutine),
)
_ = err // syscall.Errno (valid when the call sets last-error)
_ = r1 // INTfunction WSARecvFrom(
s: NativeUInt; // SOCKET
lpBuffers: Pointer; // WSABUF*
dwBufferCount: DWORD; // DWORD
lpNumberOfBytesRecvd: Pointer; // DWORD* optional, out
lpFlags: Pointer; // DWORD* in/out
lpFrom: Pointer; // SOCKADDR* optional, out
lpFromlen: Pointer; // INT* optional, in/out
lpOverlapped: Pointer; // OVERLAPPED* optional, in/out
lpCompletionRoutine: Pointer // LPWSAOVERLAPPED_COMPLETION_ROUTINE optional
): Integer; stdcall;
external 'WS2_32.dll' name 'WSARecvFrom';result := DllCall("WS2_32\WSARecvFrom"
, "UPtr", s ; SOCKET
, "Ptr", lpBuffers ; WSABUF*
, "UInt", dwBufferCount ; DWORD
, "Ptr", lpNumberOfBytesRecvd ; DWORD* optional, out
, "Ptr", lpFlags ; DWORD* in/out
, "Ptr", lpFrom ; SOCKADDR* optional, out
, "Ptr", lpFromlen ; INT* optional, in/out
, "Ptr", lpOverlapped ; OVERLAPPED* optional, in/out
, "Ptr", lpCompletionRoutine ; LPWSAOVERLAPPED_COMPLETION_ROUTINE optional
, "Int") ; return: INT●WSARecvFrom(s, lpBuffers, dwBufferCount, lpNumberOfBytesRecvd, lpFlags, lpFrom, lpFromlen, lpOverlapped, lpCompletionRoutine) = DLL("WS2_32.dll", "int WSARecvFrom(int, void*, dword, void*, void*, void*, void*, void*, void*)")
# 呼び出し: WSARecvFrom(s, lpBuffers, dwBufferCount, lpNumberOfBytesRecvd, lpFlags, lpFrom, lpFromlen, lpOverlapped, lpCompletionRoutine)
# s : SOCKET -> "int"
# lpBuffers : WSABUF* -> "void*"
# dwBufferCount : DWORD -> "dword"
# lpNumberOfBytesRecvd : DWORD* optional, out -> "void*"
# lpFlags : DWORD* in/out -> "void*"
# lpFrom : SOCKADDR* optional, out -> "void*"
# lpFromlen : INT* optional, 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 WSARecvFrom(
s: usize, // SOCKET
lpBuffers: [*c]WSABUF, // WSABUF*
dwBufferCount: u32, // DWORD
lpNumberOfBytesRecvd: [*c]u32, // DWORD* optional, out
lpFlags: [*c]u32, // DWORD* in/out
lpFrom: [*c]SOCKADDR, // SOCKADDR* optional, out
lpFromlen: [*c]i32, // INT* optional, in/out
lpOverlapped: [*c]OVERLAPPED, // OVERLAPPED* optional, in/out
lpCompletionRoutine: ?*anyopaque // LPWSAOVERLAPPED_COMPLETION_ROUTINE optional
) callconv(std.os.windows.WINAPI) i32;proc WSARecvFrom(
s: uint, # SOCKET
lpBuffers: ptr WSABUF, # WSABUF*
dwBufferCount: uint32, # DWORD
lpNumberOfBytesRecvd: ptr uint32, # DWORD* optional, out
lpFlags: ptr uint32, # DWORD* in/out
lpFrom: ptr SOCKADDR, # SOCKADDR* optional, out
lpFromlen: ptr int32, # INT* optional, in/out
lpOverlapped: ptr OVERLAPPED, # OVERLAPPED* optional, in/out
lpCompletionRoutine: pointer # LPWSAOVERLAPPED_COMPLETION_ROUTINE optional
): int32 {.importc: "WSARecvFrom", stdcall, dynlib: "WS2_32.dll".}pragma(lib, "ws2_32");
extern(Windows)
int WSARecvFrom(
size_t s, // SOCKET
WSABUF* lpBuffers, // WSABUF*
uint dwBufferCount, // DWORD
uint* lpNumberOfBytesRecvd, // DWORD* optional, out
uint* lpFlags, // DWORD* in/out
SOCKADDR* lpFrom, // SOCKADDR* optional, out
int* lpFromlen, // INT* optional, in/out
OVERLAPPED* lpOverlapped, // OVERLAPPED* optional, in/out
void* lpCompletionRoutine // LPWSAOVERLAPPED_COMPLETION_ROUTINE optional
);ccall((:WSARecvFrom, "WS2_32.dll"), stdcall, Int32,
(Csize_t, Ptr{WSABUF}, UInt32, Ptr{UInt32}, Ptr{UInt32}, Ptr{SOCKADDR}, Ptr{Int32}, Ptr{OVERLAPPED}, Ptr{Cvoid}),
s, lpBuffers, dwBufferCount, lpNumberOfBytesRecvd, lpFlags, lpFrom, lpFromlen, 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}
# lpFrom : SOCKADDR* optional, out -> Ptr{SOCKADDR}
# lpFromlen : INT* optional, in/out -> Ptr{Int32}
# 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 WSARecvFrom(
uintptr_t s,
void* lpBuffers,
uint32_t dwBufferCount,
uint32_t* lpNumberOfBytesRecvd,
uint32_t* lpFlags,
void* lpFrom,
int32_t* lpFromlen,
void* lpOverlapped,
void* lpCompletionRoutine);
]]
local ws2_32 = ffi.load("ws2_32")
-- ws2_32.WSARecvFrom(s, lpBuffers, dwBufferCount, lpNumberOfBytesRecvd, lpFlags, lpFrom, lpFromlen, lpOverlapped, lpCompletionRoutine)
-- s : SOCKET
-- lpBuffers : WSABUF*
-- dwBufferCount : DWORD
-- lpNumberOfBytesRecvd : DWORD* optional, out
-- lpFlags : DWORD* in/out
-- lpFrom : SOCKADDR* optional, out
-- lpFromlen : INT* optional, 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 WSARecvFrom = lib.func('__stdcall', 'WSARecvFrom', 'int32_t', ['uintptr_t', 'void *', 'uint32_t', 'uint32_t *', 'uint32_t *', 'void *', 'int32_t *', 'void *', 'void *']);
// WSARecvFrom(s, lpBuffers, dwBufferCount, lpNumberOfBytesRecvd, lpFlags, lpFrom, lpFromlen, 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 *'
// lpFrom : SOCKADDR* optional, out -> 'void *'
// lpFromlen : INT* optional, in/out -> 'int32_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", {
WSARecvFrom: { parameters: ["usize", "pointer", "u32", "pointer", "pointer", "pointer", "pointer", "pointer", "pointer"], result: "i32" },
});
// lib.symbols.WSARecvFrom(s, lpBuffers, dwBufferCount, lpNumberOfBytesRecvd, lpFlags, lpFrom, lpFromlen, lpOverlapped, lpCompletionRoutine)
// s : SOCKET -> "usize"
// lpBuffers : WSABUF* -> "pointer"
// dwBufferCount : DWORD -> "u32"
// lpNumberOfBytesRecvd : DWORD* optional, out -> "pointer"
// lpFlags : DWORD* in/out -> "pointer"
// lpFrom : SOCKADDR* optional, out -> "pointer"
// lpFromlen : INT* optional, 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 WSARecvFrom(
size_t s,
void* lpBuffers,
uint32_t dwBufferCount,
uint32_t* lpNumberOfBytesRecvd,
uint32_t* lpFlags,
void* lpFrom,
int32_t* lpFromlen,
void* lpOverlapped,
void* lpCompletionRoutine);
C, "WS2_32.dll");
// $ffi->WSARecvFrom(s, lpBuffers, dwBufferCount, lpNumberOfBytesRecvd, lpFlags, lpFrom, lpFromlen, lpOverlapped, lpCompletionRoutine);
// s : SOCKET
// lpBuffers : WSABUF*
// dwBufferCount : DWORD
// lpNumberOfBytesRecvd : DWORD* optional, out
// lpFlags : DWORD* in/out
// lpFrom : SOCKADDR* optional, out
// lpFromlen : INT* optional, 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 WSARecvFrom(
long s, // SOCKET
Pointer lpBuffers, // WSABUF*
int dwBufferCount, // DWORD
IntByReference lpNumberOfBytesRecvd, // DWORD* optional, out
IntByReference lpFlags, // DWORD* in/out
Pointer lpFrom, // SOCKADDR* optional, out
IntByReference lpFromlen, // INT* optional, in/out
Pointer lpOverlapped, // OVERLAPPED* optional, in/out
Callback lpCompletionRoutine // LPWSAOVERLAPPED_COMPLETION_ROUTINE optional
);
}@[Link("ws2_32")]
lib LibWS2_32
fun WSARecvFrom = WSARecvFrom(
s : LibC::SizeT, # SOCKET
lpBuffers : WSABUF*, # WSABUF*
dwBufferCount : UInt32, # DWORD
lpNumberOfBytesRecvd : UInt32*, # DWORD* optional, out
lpFlags : UInt32*, # DWORD* in/out
lpFrom : SOCKADDR*, # SOCKADDR* optional, out
lpFromlen : Int32*, # INT* optional, 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 WSARecvFromNative = Int32 Function(UintPtr, Pointer<Void>, Uint32, Pointer<Uint32>, Pointer<Uint32>, Pointer<Void>, Pointer<Int32>, Pointer<Void>, Pointer<Void>);
typedef WSARecvFromDart = int Function(int, Pointer<Void>, int, Pointer<Uint32>, Pointer<Uint32>, Pointer<Void>, Pointer<Int32>, Pointer<Void>, Pointer<Void>);
final WSARecvFrom = DynamicLibrary.open('WS2_32.dll')
.lookupFunction<WSARecvFromNative, WSARecvFromDart>('WSARecvFrom');
// s : SOCKET -> UintPtr
// lpBuffers : WSABUF* -> Pointer<Void>
// dwBufferCount : DWORD -> Uint32
// lpNumberOfBytesRecvd : DWORD* optional, out -> Pointer<Uint32>
// lpFlags : DWORD* in/out -> Pointer<Uint32>
// lpFrom : SOCKADDR* optional, out -> Pointer<Void>
// lpFromlen : INT* optional, in/out -> Pointer<Int32>
// lpOverlapped : OVERLAPPED* optional, in/out -> Pointer<Void>
// lpCompletionRoutine : LPWSAOVERLAPPED_COMPLETION_ROUTINE optional -> Pointer<Void>
// 文字列は package:ffi の "...".toNativeUtf16()/toNativeUtf8() で変換。{$mode objfpc}{$H+}
function WSARecvFrom(
s: NativeUInt; // SOCKET
lpBuffers: Pointer; // WSABUF*
dwBufferCount: DWORD; // DWORD
lpNumberOfBytesRecvd: Pointer; // DWORD* optional, out
lpFlags: Pointer; // DWORD* in/out
lpFrom: Pointer; // SOCKADDR* optional, out
lpFromlen: Pointer; // INT* optional, in/out
lpOverlapped: Pointer; // OVERLAPPED* optional, in/out
lpCompletionRoutine: Pointer // LPWSAOVERLAPPED_COMPLETION_ROUTINE optional
): Integer; stdcall;
external 'WS2_32.dll' name 'WSARecvFrom';import Foreign
import Foreign.C.Types
import Foreign.C.String
foreign import stdcall safe "WSARecvFrom"
c_WSARecvFrom :: CUIntPtr -> Ptr () -> Word32 -> Ptr Word32 -> Ptr Word32 -> Ptr () -> Ptr Int32 -> 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
-- lpFrom : SOCKADDR* optional, out -> Ptr ()
-- lpFromlen : INT* optional, in/out -> Ptr Int32
-- lpOverlapped : OVERLAPPED* optional, in/out -> Ptr ()
-- lpCompletionRoutine : LPWSAOVERLAPPED_COMPLETION_ROUTINE optional -> Ptr ()
-- 要 GHC(Windows)。stdcall は x64 では ccall として扱われる。ブロックする API は safe 呼び出し推奨。open Ctypes
open Foreign
let wsarecvfrom =
foreign "WSARecvFrom"
(size_t @-> (ptr void) @-> uint32_t @-> (ptr uint32_t) @-> (ptr uint32_t) @-> (ptr void) @-> (ptr int32_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) *)
(* lpFrom : SOCKADDR* optional, out -> (ptr void) *)
(* lpFromlen : INT* optional, in/out -> (ptr int32_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 ("WSARecvFrom" wsarecv-from :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-from :pointer) ; SOCKADDR* optional, out
(lp-fromlen :pointer) ; INT* optional, 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 $WSARecvFrom = Win32::API::More->new('WS2_32',
'int WSARecvFrom(WPARAM s, LPVOID lpBuffers, DWORD dwBufferCount, LPVOID lpNumberOfBytesRecvd, LPVOID lpFlags, LPVOID lpFrom, LPVOID lpFromlen, LPVOID lpOverlapped, LPVOID lpCompletionRoutine)');
# my $ret = $WSARecvFrom->Call($s, $lpBuffers, $dwBufferCount, $lpNumberOfBytesRecvd, $lpFlags, $lpFrom, $lpFromlen, $lpOverlapped, $lpCompletionRoutine);
# s : SOCKET -> WPARAM
# lpBuffers : WSABUF* -> LPVOID
# dwBufferCount : DWORD -> DWORD
# lpNumberOfBytesRecvd : DWORD* optional, out -> LPVOID
# lpFlags : DWORD* in/out -> LPVOID
# lpFrom : SOCKADDR* optional, out -> LPVOID
# lpFromlen : INT* optional, in/out -> LPVOID
# lpOverlapped : OVERLAPPED* optional, in/out -> LPVOID
# lpCompletionRoutine : LPWSAOVERLAPPED_COMPLETION_ROUTINE optional -> LPVOID
# 値渡し構造体は pack() した文字列、または Win32::API::Struct を使用。
# コールバック(関数ポインタ)は Perl sub を直接渡せません。Win32::API::Callback を使用してください。関連項目
- f WSACloseEvent — イベントオブジェクトハンドルを閉じて解放する。
- f WSACreateEvent — 新しいイベントオブジェクトを作成する。
- f WSAGetOverlappedResult — オーバーラップ操作の完了結果を取得する。
- f WSASend — 接続済みソケットへデータを送信する。
- f WSASendTo — 宛先アドレスを指定してデータグラムを送信する。
- f WSASocketW — プロトコル情報やフラグを指定してソケットを作成する。
- f WSAWaitForMultipleEvents — 複数のイベントオブジェクトがシグナルになるまで待機する。
- f sendto — 指定アドレス宛にソケットでデータを送信する。