我应如何将char dbcc_name [1]转换为Delphi?

我在将以下C ++代码转换为Delphi时遇到问题。 这是代码:

char dbcc_name[1]

这就是我的想法:

dbcc_name : array [0..0] of Char;

但是,我知道该字段应该返回一个名称,而不仅仅是一个字符。

所以,也许是这样的:

dbcc_name: array of Char;

现在,这看起来不错,但是无法预测名称的持续时间,它可能会返回一些带有大量红宝石和#0终止符的东西,但这是-我认为-不是正确的方法。 使用指向此数组的指针是否明智? 喜欢:

dbcc_name: pchar;

谢谢。

wang787890 回答:我应如何将char dbcc_name [1]转换为Delphi?

您第一次是对的,只是数据类型错误。请改用AnsiChar,在C / C ++中为char

dbcc_name: array[0..0] of AnsiChar;

在Delphi 2009+中,CharWideChar的别名,在C / C ++中,其别名为Windows上的wchar_t和其他平台上的char16_t

也就是说,在C / C ++中,当一个1元素数组表示可变长度数据时,它在结构中存在是有意义的,并且是该结构中的最后一个字段。在这种情况下,该结构通常存在于更大的已分配内存块中。在C / C ++中没有检查数组边界的方法,只要数组的内容不超过分配该数组的内存的边界,它的内容就可以超过该数组的边界。 em>衰减到指向第一个元素的指针。在C语言中,使用这种方法定义一个结构是可以直接在其内部嵌入可变长度数据的,这可以通过名称来引用,而不必将数据分配到内存中的其他位置是很常见的。这在内存有限的嵌入式系统中特别有用。

Win32 API中有几种结构使用此方法处理可变长度数据。 Raymond Chen在他的博客中对此进行了更详细的讨论:

Why do some structures end with an array of size 1?

,

您很可能会使用 array[0..0] of char 或仅使用 char,但有一些注意事项。下面的代码假设您使用的是 Windows API,我根据与您的描述匹配的特定 Windows 消息记录做出假设。

如果您在 C 中使用 char dbcc_name[1] 中定义的 DEV_BROADCAST_DEVICEINTERFACE,那么它在 char 结构中是一个 DEV_BROADCAST_DEVICEINTERFACE_A,但在 wchar_t 结构中是一个 DEV_BROADCAST_DEVICEINTERFACE_W }} 结构体。注意:C 中的 char 在 Delphi 中映射到 AnsiCharwchar_t 在 Delphi 中映射到 char

对于 W 结构,我在 Delphi 中将其声明为 dbcc_name: char; 以供阅读,我只是使用 PChar(@ARecordPtr^.dbcc_name)。您的 C++ 示例似乎使用了 A 结构,直接转换为 Delphi 意味着使用带有 AnsiChar 的 A 结构并使用 PAnsiChar 读取,只需替换上面的代码即可。

然而,一个新的 Delphi 项目将默认使用 Windows API 的 Unicode 版本(或 W 导入),这就是为什么我的下面的示例是为 Unicode 编写的。

在我的实现中,我只是将它定义为 char。一些开发人员喜欢 array[0..0] of char 语法,因为它在那个位置留下了可变长度数组的线索。这是一个更准确的翻译,但我发现它没有什么价值。

示例:

PDEV_BROADCAST_DEVICEINTERFACE = ^DEV_BROADCAST_DEVICEINTERFACE;
DEV_BROADCAST_DEVICEINTERFACE = record
  dbcc_size: DWORD;
  dbcc_devicetype: DWORD; // = DBT_DEVTYP_DEVICEINTERFACE
  dbcc_reserved: DWORD;
  dbcc_classguid: TGUID;
  dbcc_name: Char; // <--- [HERE IT IS]. Use AnsiChar is using the A record instead of the W Record
end;


并使用它

procedure TFoo.WMDeviceChange(var AMessage: TMessage);
var
  LUsbDeviceName: string;
  LPDeviceBroadcastHeader: PDEV_BROADCAST_HDR;
  LPBroadcastDeviceIntf: PDEV_BROADCAST_DEVICEINTERFACE;
begin
  if (AMessage.wParam = DBT_DEVICEARRIVAL) then
  begin
    LPDeviceBroadcastHeader := PDEV_BROADCAST_HDR(AMessage.LParam);

    if LPDeviceBroadcastHeader^.dbch_devicetype = DBT_DEVTYP_DEVICEINTERFACE then
    begin 
      LPBroadcastDeviceIntf := PDEV_BROADCAST_DEVICEINTERFACE(LPDeviceBroadcastHeader);
      LUsbDeviceName := PChar(@LPBroadcastDeviceIntf^.dbcc_name); // <--- [HERE IT IS USED] Use PAnsiChar if using the A Record instead of the W Record
      ... 
    end;
  end;
end;

在我的 post on pointers and structures 中查看更多信息,有关单个字符数组的奇怪使用的更多解释,请参阅我的 post on arrays and pointer math 中的“具有可变长度数组的记录”部分。

本文链接:https://www.f2er.com/3131138.html

大家都在问