You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Delphi的BinToHex和HexToBin实现Hex字符串与PByteArray互转?

Delphi中使用BinToHex和HexToBin实现Hex字符串与PByteArray的正确转换

原代码的核心错误

BuffertoHex函数问题

  • 传参错误:你把@ABuf传给了BinToHex,但ABuf本身就是指向缓冲区的指针,@ABuf取的是指针变量自己的内存地址,导致转换的是指针本身的数据,而非目标缓冲区内容——这就是开头出现异常值的原因。
  • 长度错误:用sizeof(ABuf)作为转换长度,实际这是指针类型的大小(32位下4字节,64位下8字节),不是传入的实际缓冲区长度ALen,导致转换范围完全错误。
  • 字符串长度计算不匹配:如果要生成带空格分隔的Hex字符串,3 * ALen -1的长度是对的,但原代码没处理空格插入,和BinToHex的默认无空格输出不匹配。

HexToBuffer函数问题

  • 动态数组未初始化:TArray初始长度为0,FillChar只填充了数组的指针变量,根本没碰数组内容。
  • 未分配内存:转换前没根据Hex字符串长度计算所需字节数,也没调用SetLength给数组分配空间,HexToBin根本没有有效内存可写入。

正确实现代码

1. 缓冲区转Hex字符串(支持两种格式)

// 生成无空格的Hex字符串
function BufferToHex(ABuf: PByte; ALen: Cardinal): string; overload;
begin
  SetLength(Result, 2 * ALen);
  BinToHex(ABuf, PChar(Result), ALen);
end;

// 生成带空格分隔的Hex字符串(和示例格式一致)
function BufferToHexWithSpace(ABuf: PByte; ALen: Cardinal): string; overload;
var
  I: Integer;
begin
  if ALen = 0 then
  begin
    Result := '';
    Exit;
  end;
  // 先生成无空格的基础字符串
  SetLength(Result, 2 * ALen);
  BinToHex(ABuf, PChar(Result), ALen);
  // 从后往前插入空格,避免索引混乱
  for I := ALen - 1 downto 1 do
    Insert(' ', Result, 2 * I + 1);
end;

// 重载:TArray<Byte>直接转无空格Hex
function BufferToHex(ABytes: TArray<Byte>): string; overload;
begin
  Result := BufferToHex(PByte(ABytes), Length(ABytes));
end;

// 重载:TArray<Byte>直接转带空格Hex
function BufferToHexWithSpace(ABytes: TArray<Byte>): string; overload;
begin
  Result := BufferToHexWithSpace(PByte(ABytes), Length(ABytes));
end;

2. Hex字符串转PByteArray

function HexToBuffer(LText: string): PByteArray; overload;
var
  ABytes: TArray<Byte>;
  CleanHex: string;
  ByteCount: Integer;
begin
  // 先清除字符串中的空格(兼容带空格和不带空格的输入)
  CleanHex := StringReplace(LText, ' ', '', [rfReplaceAll]);
  if Length(CleanHex) mod 2 <> 0 then
    raise Exception.Create('Hex字符串长度必须为偶数');
  
  // 计算需要的字节数,分配数组内存
  ByteCount := Length(CleanHex) div 2;
  SetLength(ABytes, ByteCount);
  if ByteCount > 0 then
    HexToBin(PChar(CleanHex), PByte(ABytes), ByteCount);
  
  // 将动态数组转为PByteArray(注意:若原动态数组被释放,指针会失效)
  Result := PByteArray(ABytes);
end;

注意事项

  • 关于PByteArray的生命周期:动态数组赋值给指针后,若原数组被Delphi的自动内存管理回收,指针会变成野指针。如果需要长期持有指针,建议用GetMem手动分配内存,再把转换后的字节复制进去。
  • BinToHex和HexToBin的重载:确保参数类型匹配,避免隐式转换导致的意外错误。

内容的提问来源于stack exchange,提问作者Underhood

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 16:45:47