我应该用 IcmpCloseHandle 关闭句柄吗?
Should I close a handle with IcmpCloseHandle?
我尝试编写一个 ping 线程来搜索连接到本地网络的设备。我需要避免使用 Indy,因为它适用于 windows.
中的管理帐户
我翻译了msdn的c++例子。我应该使用 IcmpCloseHandle 吗?如果是这样,我为什么要关闭只是一个基数变量的句柄。如果不是,那么方法是什么?
function IcmpSendEcho(ICMPHandle: Cardinal; DestinationAddress: Integer; RequestData: Pointer; RequestSize: Word; RequestOptions: Pointer; ReplyBuffer: Pointer; ReplySize: Cardinal; TimeOut: Cardinal): Cardinal; stdcall; external 'icmp.dll';
function TForm1.Ping(IPAddress: string; TimeOut: Integer): Integer;
var
ICMPHandle: Cardinal;
DestinationAddress: Integer;
ReplyBuffer: pICMPEchoReply;
RequestData: array[0..31] of AnsiChar;
ReplySize: Cardinal;
begin
ICMPHandle := IcmpCreateFile;
DestinationAddress := inetaddr(pansichar(AnsiString(IPAddress)));
RequestData := 'data buffer';
ReplySize := SizeOf(ticmpechoreply) + SizeOf(RequestData);
ReplyBuffer := AllocMem(ReplySize);
IcmpSendEcho(ICMPHandle, DestinationAddress, @RequestData, SizeOf(requestdata), nil, ReplyBuffer, ReplySize, TimeOut);
Result := replybuffer.Status;
FreeMem(ReplyBuffer);
end;
IcmpCreateFile
的文档相当薄弱。它应该说明由 IcmpCreateFile
成功返回的句柄应该在不再需要时通过调用 IcmpCloseHandle
来关闭。所以是的,您确实需要致电 IcmpCloseHandle
.
你误以为IcmpCreateFile
returns一个Cardinal
。 Cardinal
是 32 位类型,但 IcmpCreateFile
returns HANDLE
是指针大小的类型。在 64 位上编译时,您的代码将失败。您在 IcmpSendEcho
header 翻译中使用的其他一些类型看起来很可疑。如果我是你,我要么努力研究如何翻译 Win32 header 文件,要么找到并使用值得信赖的 header 翻译。
我还想强调您的代码不会尝试处理任何错误。你这是在玩火。我们在 SO 上看到了很多次,我相信我已经在很多早期场合亲自告诉过你这件事。因此,请阅读您调用的每个 API 函数的文档,并适当地处理错误。
除非您是 Win32 API header 翻译和使用方面的专家,否则您很可能会生成有缺陷的代码。使用第三方 header 翻译可能是明智的,例如,JEDI。
我尝试编写一个 ping 线程来搜索连接到本地网络的设备。我需要避免使用 Indy,因为它适用于 windows.
中的管理帐户我翻译了msdn的c++例子。我应该使用 IcmpCloseHandle 吗?如果是这样,我为什么要关闭只是一个基数变量的句柄。如果不是,那么方法是什么?
function IcmpSendEcho(ICMPHandle: Cardinal; DestinationAddress: Integer; RequestData: Pointer; RequestSize: Word; RequestOptions: Pointer; ReplyBuffer: Pointer; ReplySize: Cardinal; TimeOut: Cardinal): Cardinal; stdcall; external 'icmp.dll';
function TForm1.Ping(IPAddress: string; TimeOut: Integer): Integer;
var
ICMPHandle: Cardinal;
DestinationAddress: Integer;
ReplyBuffer: pICMPEchoReply;
RequestData: array[0..31] of AnsiChar;
ReplySize: Cardinal;
begin
ICMPHandle := IcmpCreateFile;
DestinationAddress := inetaddr(pansichar(AnsiString(IPAddress)));
RequestData := 'data buffer';
ReplySize := SizeOf(ticmpechoreply) + SizeOf(RequestData);
ReplyBuffer := AllocMem(ReplySize);
IcmpSendEcho(ICMPHandle, DestinationAddress, @RequestData, SizeOf(requestdata), nil, ReplyBuffer, ReplySize, TimeOut);
Result := replybuffer.Status;
FreeMem(ReplyBuffer);
end;
IcmpCreateFile
的文档相当薄弱。它应该说明由 IcmpCreateFile
成功返回的句柄应该在不再需要时通过调用 IcmpCloseHandle
来关闭。所以是的,您确实需要致电 IcmpCloseHandle
.
你误以为IcmpCreateFile
returns一个Cardinal
。 Cardinal
是 32 位类型,但 IcmpCreateFile
returns HANDLE
是指针大小的类型。在 64 位上编译时,您的代码将失败。您在 IcmpSendEcho
header 翻译中使用的其他一些类型看起来很可疑。如果我是你,我要么努力研究如何翻译 Win32 header 文件,要么找到并使用值得信赖的 header 翻译。
我还想强调您的代码不会尝试处理任何错误。你这是在玩火。我们在 SO 上看到了很多次,我相信我已经在很多早期场合亲自告诉过你这件事。因此,请阅读您调用的每个 API 函数的文档,并适当地处理错误。
除非您是 Win32 API header 翻译和使用方面的专家,否则您很可能会生成有缺陷的代码。使用第三方 header 翻译可能是明智的,例如,JEDI。