我应该用 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.

你误以为IcmpCreateFilereturns一个CardinalCardinal 是 32 位类型,但 IcmpCreateFile returns HANDLE 是指针大小的类型。在 64 位上编译时,您的代码将失败。您在 IcmpSendEcho header 翻译中使用的其他一些类型看起来很可疑。如果我是你,我要么努力研究如何翻译 Win32 header 文件,要么找到并使用值得信赖的 header 翻译。

我还想强调您的代码不会尝试处理任何错误。你这是在玩火。我们在 SO 上看到了很多次,我相信我已经在很多早期场合亲自告诉过你这件事。因此,请阅读您调用的每个 API 函数的文档,并适当地处理错误。

除非您是 Win32 API header 翻译和使用方面的专家,否则您很可能会生成有缺陷的代码。使用第三方 header 翻译可能是明智的,例如,JEDI。