如何将shorttring数组传递给方法

时间:2011-10-28 10:10:07

标签: arrays delphi delphi-2007

我想创建一个以shorttring数组作为参数

的过程
procedure f(const a, b: Array of shortstring);

我想用已知长度的数组和已知长度的短串来称呼它,例如

var
  A, B: array[1..2] of string[5];
  C, D: array[1..40] of string[12];
begin
  f(A,B);
  f(C,D);
end;

这导致编译器错误E2008不兼容的类型。 这是为什么?我可以编写一个可以接受shorttring数组(任意长度的数组/字符串)的过程吗?

为什么要使用shortstring?

缺点是现有记录中的字段。这些记录有很多短线串。为了将数据从turbo power B-Tree Filer迁移到SQL数据库,一步是将记录转换为数据集,然后返回记录,以确认所有字段都在两个方向上正确转换。我一直在记录上使用CompareMem来检查这一点,但它没有提供关于转换错误所在的字段的足够信息。因此创建了一个小程序,从记录定义中可以生成代码进行比较这两个记录。对于这个代码生成器,我需要一个函数来比较shorttrings。它最终在短串上使用CompareMem

4 个答案:

答案 0 :(得分:7)

ShortString长度为0到255个字符。 ShortString的长度可以动态改变,但是内存是静态分配的256个字节,第一个字节存储字符串的长度,剩下的255个字节可用于字符,以这种方式声明的whilist字符串[5]仅分配为类型要求的内存很多(长度为5字节+ 1字节)。 你可以使用类型

type
    MyString = string[5];
...
procedure f(const a, b: Array of MyString);
...

var
    A, B: array[1..2] of MyString;
begin
    f(A,B);
end;

答案 1 :(得分:1)

在类似的情况下,我使用了以下内容:

type
  TOpenArrayOfOpenString = record
  strict private
    FSizeOfString: Integer;
    FpStart: PChar;
    FArrayLength: Integer;
    function GetItemPtr(AIndex: Integer): PShortString;
  public
    constructor Init(var AFirstString: Openstring; AArrayLength: Integer);
    function Equals(const AArray: TOpenArrayOfOpenString): Boolean;

    property SizeOfString: Integer read FSizeOfString;
    property pStart: PChar read FpStart;
    property ArrayLength: Integer read FArrayLength;
    property ItemPtrs[AIndex: Integer]: PShortString read GetItemPtr; default;
  end;

{ TOpenArrayOfOpenString }

constructor TOpenArrayOfOpenString.Init(var AFirstString: Openstring; AArrayLength: Integer);
begin
  FSizeOfString := SizeOf(AFirstString);
  FpStart := @AFirstString[0]; // incl. length byte!
  FArrayLength := AArrayLength;
end;

function TOpenArrayOfOpenString.Equals(const AArray: TOpenArrayOfOpenString): Boolean;
begin
  Result := CompareMem(pStart, AArray.pStart, SizeOfString * ArrayLength);
end;

function TOpenArrayOfOpenString.GetItemPtr(AIndex: Integer): PShortString;
begin
  Result := PShortString(pStart + AIndex * SizeOfString);
end;

您可以像这样使用它:

procedure f(const a: TOpenArrayOfOpenString);
var
  i: Integer;
begin
  for i := 0 to Pred(a.ArrayLength) do
    Writeln(a[i]^);
end;

procedure Test;
var
  A: array[1..2] of string[5];
  C: array[1..40] of string[12];
begin
  f(TOpenArrayOfOpenString.Init(A[1], Length(A)));
  f(TOpenArrayOfOpenString.Init(C[1], Length(C)));
end;

它并不像语言中内置的解决方案那样优雅,而且它有点hacky,因为它依赖于事实/希望/ ...数组中的字符串是连续布局的。但它现在已经有一段时间了。

答案 2 :(得分:0)

   type
      shortStrings =array[1..2] of string[5];  
    ...
    a,b : shortString;
    ..
    procedure rock(a,b : shortStrings);
    ..

答案 3 :(得分:-1)

您正在组合两种不同类型的开放阵列。

首先,有经典的Turbo Pascal“字符串”(在Delphi IIRC中也称为“openstring”),它本质上是字符串[255]。由于string [255]是所有shorttrings的超集,open数组方面只是将所有shorttring类型转换为它。

“xx数组”语法是Delphi(4+?)开放数组。它是一个任何类型的开放数组,而不仅仅是字符串,调用它的语法是f(nonarrayparam,[arrayelement0,arrayelement1]);

不知何故,你似乎混合了两种语法,甚至通过添加CONST来聚合它,它通过引用传递并排除转换。

我认为你认为shorttring具有性能优势。在某些情况下,它有。 Open数组不是其中之一。甚至没有TP: - )