您的示例代码不起作用,因为您正在混合 shortstring const 和 pointer 和 string - 正如 Rob 在他的评论中所说的那样。
而且您的代码与 KLV 或 TLV 编码无关。
这里可能是一个 TLV 编码示例(我只展示了字符串编码,但您可以添加其他类型):
type
TTLVType = (tlvUnknown, tlvString, tlvInteger);
function EncodeToTLV(const aString: WideString): TBytes;
var Len: integer;
begin
Len := length(aString)*2;
SetLength(result,Len+sizeof(TTLVType)+sizeof(integer));
Result[0] := ord(tlvString); // Type
PInteger(@Result[sizeof(TTLVType)])^ := Len; // Length
move(pointer(aString)^,Result[sizeof(TTLVType)+sizeof(integer)],Len); // Value
end;
function DecodeStringFromTLV(const aValue: TBytes): WideString;
begin
if (length(aValue)<3) or (aValue[0]<>ord(tlvString)) or
(PInteger(@aValue[sizeof(TTLVType)])^<>length(aValue)-sizeof(TTLVType)-sizeof(integer)) then
raise EXception.Create('Invalid input format');
SetString(result,PWideChar(@Result[sizeof(TTLVType)+sizeof(integer)]),PInteger(@aValue[sizeof(TTLVType)])^ div 2);
end;
我在这里使用了WideString,因为它可以安全地存储任何 Unicode 内容,即使在 Delphi 2009 之前的编译器版本上也是如此。
你可以使用记录代替我的指针算法:
type
TTLVHeader = packed record
ContentType: TTLVType;
ContentLength: integer;
Content: array[0..1000] of byte; // but real length will vary
end;
PTLVHeader = ^TTLVHeader;
function EncodeToTLV(const aString: WideString): TBytes;
var Len: integer;
begin
Len := length(aString)*2;
SetLength(result,Len+sizeof(TTLVType)+sizeof(integer));
with PTLVHeader(result)^ do
begin
ContentType := tlvString;
ContentLength := Len;
move(pointer(aString)^,Content,Len);
end;
end;
KLV 可以使用类似的编码,但在标头中添加一个整数键。