如何用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
相关产品推荐
相关产品推荐

