【问题标题】:What is this code doing with pointers?这段代码用指针做什么?
【发布时间】:2014-04-23 23:29:54
【问题描述】:

我仍然没有很好地理解指针在 Delphi 中是如何工作的。在查看我的库时,在我通常使用的函数GetIPAddress(用于获取本地机器的 IP 地址)中,我遇到了一个使用指针的奇怪转换(下面标记的行)。这不是我写的,但不久前在某个地方找到了它......

uses
  Winsock;

function GetIPAddress: string;
type
  pu_long = ^u_long;
var
  varTWSAData: TWSAData;
  varPHostEnt: PHostEnt;
  varTInAddr: TInAddr;
  namebuf: array [0 .. 255] of ansichar;
begin
  try
    try
      if WSAStartup($101, varTWSAData) <> 0 then Result := ''
      else begin
        gethostname(namebuf, sizeof(namebuf));
        varPHostEnt := gethostbyname(namebuf);
        varTInAddr.S_addr := u_long(pu_long(varPHostEnt^.h_addr_list^)^); //<--- ???
        Result := WideString(inet_ntoa(varTInAddr));
      end;
    except
      Result := '';
    end;
  finally
    WSACleanup;
  end;
end;

指针到底发生了什么?

【问题讨论】:

标签: delphi pointers casting


【解决方案1】:

PHostEnt 是指向hostent 的指针,这是在 Windows API 中定义的类型。 h_addr_list 是一个 PAnsiChar 值数组,它实际上是一个字节数组(在 C 中,一个 char 和一个字节是同一个东西,这使得处理字节缓冲区的 C API 变得复杂)。

这是在说什么:

  • varPHostEnt^:取消引用指向主机的指针
  • h_addr_list^:取消引用指向字节数组数组的指针,获取第一个成员
  • pu_long cast:将第一个成员(字节数组指针)解释为 ulong 指针
  • pu_long()^: 取消引用这个指针并得到它指向的ulong
  • ulong cast:不必要,因为我们已经在处理 ulong
  • S_addr := in_addr 记录是一种变体类型,可以解释为 uint32(4 字节无符号整数)或 4 个单独字节的数组。将此 ulong(4 字节无符号整数)分配给前一种解释。

【讨论】:

  • 不要回滚... Remy 对h_addr_list 类型的真正解释是准确的。现在你又搞错了。正如您所说,这不是array of PAnsiChar。 [这里没有投票]
  • @TLama:这就是 Delphi 端的定义方式。 (嗯,实际上是一个 ^PAnsiChar。)我的解释是有意义的,而不是通过解释与使用 Delphi 的编码器将看到的不同的东西来进一步混淆问题。
  • 回滚错误。雷米是对的。这个答案是不正确的!
  • @Danny:请随意查看 winsock.pas 中的定义。
猜你喜欢
  • 1970-01-01
  • 2016-05-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多