gpt4 book ai didi

Delphi:WSAAddressToString 返回错误代码 10022 (WSAEINVAL)

转载 作者:行者123 更新时间:2023-12-03 02:14:28 29 4
gpt4 key购买 nike

我正在尝试使用 Winsock2 API 接口(interface)扫描附近的蓝牙设备的 MAC 地址。使用下面的代码我可以找到设备。但是,当我尝试使用 WSAddressToString 获取他们的地址时,收到 10022 (WSAEINVAL) 错误,提示“提供了无效的参数”。

代码是:

uses
winsock2, bt_helper;

procedure test;
var
ulFlags: u_long;
QuerySet: WSAQUERYSET;
QuerySize: u_long;
HLookup: THandle;
Result: Integer;

pCSAddr: pCSADDR_INFO;
pDeviceInfo: PBTH_DEVICE_INFO;
pResults: lpWSAQUERYSET;
Buffer: array [0..999] of Byte;

ProtocolInfo: WSAPROTOCOL_INFO;
ProtocolInfoSize: Integer;

BufferLength, AddressSize: LongWord;
addressAsString: array [0..1999] of Char;
begin

WSAStartup ($0202, Data);

ulFlags:=
LUP_CONTAINERS or //device inquiry
LUP_RETURN_NAME or //Friendly device name (if available) will be returned in lpszServiceInstanceName
LUP_RETURN_ADDR or //BTH_ADDR will be returned in lpcsaBuffer member of WSAQUERYSET
LUP_FLUSHCACHE ; //Flush the device cache for all inquiries, except for the first inquiry

QuerySize:= SizeOf(WSAQuerySet);
ZeroMemory (@QuerySet, SizeOf(QuerySet));

QuerySet.dwNameSpace:= NS_BTH;
QuerySet.dwSize:= QuerySize;

Result:= WSALookupServiceBegin(@QuerySet, ulFlags, HLookup);

if Result = 0 then
begin
while true do
begin
bufferLength:= sizeof(buffer);
pResults:= lpWSAQUERYSET(@buffer);
Result:= WSALookupServiceNext (HLOOKUP, ulFlags, bufferLength, pResults);

if Result = 0 then
begin
// Get the device info, name, address, etc.
Memo1.Lines.Add(Format('The service instance name is %s', [pResults.lpszServiceInstanceName]));
//pCSAddr.LocalAddr.lpSockaddr.sa_family:= AF_INET;
pCSAddr:= PCSADDR_INFO(pResults.lpcsaBuffer);
pDeviceInfo:= PBTH_DEVICE_INFO(pResults.lpBlob);

// Print the local Bluetooth device address ...
AddressSize:= sizeof(addressAsString);

if WSAAddressToString(pCSAddr.LocalAddr.lpSockaddr^, pCSAddr.LocalAddr.iSockaddrLength,
@ProtocolInfo, @AddressAsString, AddressSize) = 0
then
Memo1.Lines.Add(Format ('The localAddress: %s', [AddressAsString]))
else
Memo1.Lines.Add(Format ('WSAAddressToString for localAddress failed with error code %d: %s',
[WSAGetLastError, SysErrorMessage (WSAGetLastError)]));

// Print the remote Bluetooth device address ...
AddressSize:= sizeof(addressAsString);
IF WSAAddressToString(pCSAddr.RemoteAddr.lpSockaddr^, pCSAddr.RemoteAddr.iSockaddrLength,
@ProtocolInfo, @AddressAsString, Addresssize) = 0
then
Memo1.Lines.Add (Format ('The remote device address: %s', [AddressAsString]))
else
Memo1.Lines.Add (Format ('WSAAddressToString for remoteAddress failed with error code %d: %s',
[WSAGetLastError, SysErrorMessage(WSAGetLastError)]));
end
else
begin
Memo1.Lines.Add(SysErrorMessage(WSAGetLastError));
break;
end;
end;
end;
WSALookupServiceEnd(HLookup);

这是备忘录中的结果:

The service instance name is BTDevice1
WSAAddressToString for localAddress failed with error code 10022: An invalid argument was supplied
WSAAddressToString for remoteAddress failed with error code 10022: An invalid argument was supplied
---------------------------------
No more results can be returned by WSALookupServiceNext

使用以下单元进行编译:

unit bt_helper;

interface

uses
winsock2, Winapi.Windows;

const
BTH_MAX_NAME_SIZE = 248;
BTHPROTO_RFCOMM= 3;
BT_PORT_ANY = -1;

type
BTH_ADDR = int64;

SOCKADDR_BTH = packed record
addressFamily :word; // Always AF_BTH
btAddr :BTH_ADDR; // Bluetooth device address
serviceClassId :TGUID; // [OPTIONAL] system will query SDP for port
port :dword; // RFCOMM channel or L2CAP PSM
end;

BTH_COD = ULONG;

_BTH_DEVICE_INFO = record
flags: ULONG; // Combination BDIF_Xxx flags
address: BTH_ADDR; // Address of remote device.
classOfDevice: BTH_COD; // Class Of Device.
name: array [0..BTH_MAX_NAME_SIZE - 1] of CHAR; // name of the device
end;
{$EXTERNALSYM _BTH_DEVICE_INFO}
BTH_DEVICE_INFO = _BTH_DEVICE_INFO;
{$EXTERNALSYM BTH_DEVICE_INFO}
PBTH_DEVICE_INFO = ^BTH_DEVICE_INFO;
{$EXTERNALSYM PBTH_DEVICE_INFO}
TBthDeviceInfo = BTH_DEVICE_INFO;
PBthDeviceInfo = PBTH_DEVICE_INFO;

implementation

end.

最佳答案

如果您阅读 documentation of WSAAddressToString如果仔细观察的话,你一定会注意到这一段:

lpProtocolInfo [in, optional] A pointer to the WSAPROTOCOL_INFO structure for a particular provider. If this is parameter is NULL, the call is routed to the provider of the first protocol supporting the address family indicated in the lpsaAddress parameter.

因此,您应该传入 nil,而不是提供虚假的 WSA_PROTOCOL 信息结构。第二个问题是您使用 SizeOf() 来确定字符串缓冲区的长度,这是不正确的,您应该使用 Length():

AddressSize:= Length(addressAsString);

if WSAAddressToString(pCSAddr.LocalAddr.lpSockaddr^, pCSAddr.LocalAddr.iSockaddrLength,
nil, @AddressAsString, AddressSize) = 0 then
begin
SetLength(AddressAsString, AddressSize-1);// resize to returned length minus last null character
...

关于Delphi:WSAAddressToString 返回错误代码 10022 (WSAEINVAL),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31218734/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com