你已经在做的事情会起作用,但你需要做一些调整。最重要的是,将你的函数变成“字符串”类型而不是“AnsiString”类型,这意味着你必须将它转换。
移动设备字符串是从 0 开始的,因此在移动设备上,您需要从索引中减去 1。或者您可以使用我的 ocopy() 或 zcopy() 函数,它们在所有平台上都执行相同的操作。如果您正在处理旧的 Windows 代码,请使用 ocopy(),它会将基于 0 的字符串本质上视为基于 1 的字符串,从而更容易移植。
const
{$IFNDEF MSWINDOWS}
STRZ = 1;
{$ELSE}
STRZ = 0;
function zcopy(sString: string; iStartZeroBased: nativeint; iLength: nativeint): string;
begin
result := '';
setlength(result, lesserof(iLength, length(sString)-iStartZerobased));
movemem32(@result[strz], @sString[(strz+iStartZeroBased)], length(result)*sizeof(char));
end;
function ocopy(sString: string; iStartOneBased: nativeint; iLength: nativeint): string;
begin
result := zcopy(sString, iStartOneBased-1, iLength);
end;
接下来,使用这段代码,它不是一个完全完整的解决方案,但会在移动设备上为您提供大部分 ansi-string 支持(围绕指针有一些轻微的警告)。但基本上你可以通过简单地将 ansistring 分配给字符串类型来转换字符串,反之亦然。我不得不从几个依赖项中破解它,所以我不保证它会开箱即用,但它应该非常接近。
unit iosbytestring;
interface
uses
sysutils, classes;
{$IFNDEF MSWINDOWS}
const STRZERO = 0;
{$ELSE}
const STRZERO = 1;
{$ENDIF}
type
Tiosansichar = packed record
private
b: byte;
class function AnsiFromChar(c: char): byte;static;
class function CharFromAnsi(b: byte): char;static;
public
function ToChar: char;
function ToOrd: byte;
class operator Implicit(const s: Tiosansichar): string;
class operator Implicit(const s: Tiosansichar): char;
class operator Implicit(const s: Tiosansichar): byte;
class operator Implicit(const s: Tiosansichar): pointer;
end;
Tiosbytestring = record
private
Fbytes: TBytes;
function GetChar(idx: nativeint): char;
procedure SetChar(idx: nativeint; const Value: char);
function GetAddrOf(idx: nativeint): pbyte;
function getbyte(idx: nativeint): byte;
procedure setbyte(idx: nativeint; const Value: byte);
public
property chars[idx: nativeint]: char read GetChar write SetChar;
property bytes[idx: nativeint]: byte read getbyte write setbyte;
property addrof[idx: nativeint]: pbyte read GetAddrOf;
class operator Implicit(const s: TIOSByteString): string;
class operator Implicit(const s: string): TIOSByteString;
class operator Add(const s1,s2: TIOSByteString): TIOSByteSTring;
class operator Add(const s1: string; const s2: TIOSByteString): TIOSByteSTring;
class operator Add(const s1: TIOSByteString; const s2: string): TIOSByteSTring;
procedure FromString(s: string);
function ToString: string;
procedure SetLength(i: nativeint);
end;
TIOSAnsiString = TIOSByteString;
{$IFNDEF MSWINDOWS}
ansistring = TIOSByteString;
utf8string = TIOSByteString;
widestring = string;
{$ENDIF}
implementation
{ iosbytestring }
class operator Tiosbytestring.Add(const s1: string;
const s2: TIOSByteString): TIOSByteSTring;
var
ss2,ss3: string;
begin
ss2 := s2.ToString;
ss3 := s1+ss2;
result.FromString(ss3);
end;
class operator Tiosbytestring.Add(const s1: TIOSByteString;
const s2: string): TIOSByteSTring;
var
ss1,ss3: string;
begin
ss1 := s1.ToString;
ss3 := ss1+s2;
result.FromString(ss3);
end;
procedure Tiosbytestring.FromString(s: string);
begin
Fbytes := TEncoding.ANSI.GetBytes(s);
end;
function Tiosbytestring.GetAddrOf(idx: nativeint): pbyte;
begin
result := @Fbytes[idx];
end;
function Tiosbytestring.getbyte(idx: nativeint): byte;
begin
result := Fbytes[idx-strzero];
end;
function Tiosbytestring.GetChar(idx: nativeint): char;
begin
result := Tiosansichar.CharFromAnsi(Fbytes[idx-strzero]);
end;
class operator Tiosbytestring.Implicit(const s: TIOSByteString): string;
begin
result := s.ToString;
end;
class operator Tiosbytestring.Implicit(const s: string): TIOSByteString;
begin
result.FromString(s);
end;
procedure Tiosbytestring.setbyte(idx: nativeint; const Value: byte);
begin
Fbytes[idx-strzero] := value;
end;
class operator Tiosbytestring.Add(const s1,
s2: TIOSByteString): TIOSByteSTring;
var
ss1,ss2,ss3: string;
begin
ss1 := s1.ToString;
ss2 := s2.ToString;
ss3 := ss1+ss2;
result.FromString(ss3);
end;
procedure Tiosbytestring.SetChar(idx: nativeint; const Value: char);
begin
Fbytes[idx-strzero] := Tiosansichar.AnsiFromChar(value);
end;
procedure Tiosbytestring.SetLength(i: nativeint);
begin
system.setlength(Fbytes,i);
end;
function Tiosbytestring.ToString: string;
begin
result := TEncoding.ANSI.GetString(Fbytes);
end;
{ Tiosansichar }
class function Tiosansichar.AnsiFromChar(c: char): byte;
var
s: string;
te: TEncoding;
b: TBytes;
begin
s := c;
b := TEncoding.ANSI.GetBytes(c);
result := b[0];
end;
class function Tiosansichar.CharFromAnsi(b: byte): char;
var
s: string;
bytes: TBytes;
begin
system.setlength(bytes, 1);
bytes[0] := b;
s := TEncoding.ANSI.GetString(bytes, 0, 1);
result := s[low(s)];
end;
class operator Tiosansichar.Implicit(const s: Tiosansichar): char;
begin
result := s.ToChar;
end;
class operator Tiosansichar.Implicit(const s: Tiosansichar): string;
begin
result := s.ToChar;
end;
class operator Tiosansichar.Implicit(const s: Tiosansichar): pointer;
begin
result := @s.b;
end;
class operator Tiosansichar.Implicit(const s: Tiosansichar): byte;
begin
result := s.b;
end;
function Tiosansichar.ToChar: char;
begin
result := CharFromAnsi(b);
end;
function Tiosansichar.ToOrd: byte;
begin
result := b;
end;
end.
所以只需添加上面的单元,将其添加到您的 uses 子句中,神奇地,您将在您的移动平台上拥有一个 ansistring 类型。继续在 windows 上使用标准 ansistring 类型。
如果一切顺利...这就是您的代码 sn-p 最终的样子。
procedure DecodeLineAddr(const aLine: AnsiString; var ByteCount: integer; var Address:Cardinal; var RecType: Integer);
var
aLineWide: string;
begin
aLineWide = aLine;
//123 4567 89 0
//:10 4640 00 0000 0600 0200 fa00 004f 7800 1e00 fb00 88
ByteCount:= StrToInt('$' + ocopy(aLineWide, 2, 2));
Address := StrToInt('$' + ocopy(aLineWide, 4, 4));
RecType := StrToInt('$' + ocopy(aLineWide, 8, 2));
end;