您第一次是对的,只是数据类型错误。请改用AnsiChar
,在C / C ++中为char
:
dbcc_name: array[0..0] of AnsiChar;
在Delphi 2009+中,Char
是WideChar
的别名,在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 中映射到 AnsiChar
,wchar_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