在运行时注册动态数组

时间:2013-02-07 19:38:21

标签: delphi runtime dynamic-arrays

当您声明动态数组时,您可以这样做,例如

var
  MyArray: array of Byte;

这样编译器知道它必须在超出范围时完成该变量(数组)。但我希望将动态数组声明为像这样的指针

var
  MyArray: Pointer;

我知道如何在运行时动态初始化(设置长度)到这样的数组。问题是编译器不知道它需要最终确定它。我想知道是否有一种方法可以告诉编译器在超出范围时将该指针最终确定为数组。当我第一次初始化阵列时,我会告诉他。

我知道这是一个黑客攻击,但我不想听到这不是一个正确的方法。我有一个非常具体的愿望(问题),我想知道是否有可能实现。我想这不是编译器魔术的编译器。

修改

我想让这个问题变得简单,但是有些人想知道更多,我会说更多。我不认为它与这个问题相关,但不管怎样,它就在这里。

我想为每条记录节省4个字节(或64位系统上的8个字节)。这更像是一件戏。我的想法是在变量记录TSimpleData中插入一个指向动态数组的指针。这些记录不接受需要完成的变量。完全明白为什么。 但是我想知道以后是否有办法注册完成。我99%肯定没有办法,但要求100%肯定没有任何伤害。贝娄是相关的相关代码。我希望FComplexData作为简单指针成为TSimpleData的一部分。

 TSimpleData = record { do not pack this record; it is compiler-generated }
    case Byte of
      atInteger:   (VInteger: Integer);
      atCardinal:  (VCardinal: Cardinal);
      atBoolean:   (VBoolean: Boolean);
      atObject:    (VObject: TObject);
      atPointer:   (VPointer: Pointer);
      atClass:     (VClass: TClass);
      atWideChar:  (VWideChar: WideChar);
      atChar:      (VChar: AnsiChar);
    {$IFDEF AnyValue_UseLargeNumbers}
      atInt64:     (VInt64: Int64);
      atExtended:  (VExtended: Extended);
    {$ENDIF}   
  end;

  TAnyValue = packed record   private
    FValueType: TValueType;   
  {$IFNDEF AnyValue_NoInterfaces}
    FInterface: IInterface;   
  {$ENDIF}
    FSimpleData: TSimpleData;
    FComplexData: array of Byte;
    ...    
  end;

2 个答案:

答案 0 :(得分:2)

没有办法按你的要求做。使编译器自动完成动态数组的唯一方法是声明一个动态数组。您无法在不实际声明的情况下将动态数组变量“插入”代码中。

声明后,您可以将指针指定给它,它将像任何其他动态数组一样被清除。如果需要,可以将该行为包装到函数中:

procedure CleanUpArray(P: Pointer);
var
  Arr: array of Byte;
begin
  Pointer(Arr) := P;
end;

如果您调用CleanUpArray(MyArray),则Pointer变量中存储的动态数组将被清除 - 其引用计数减少1,并且可能释放其内存 - 尽管该值存储在{ {1}}将保持不变。

该函数有效,因为type-cast会禁用动态数组赋值语句中固有的任何引用计数代码,因此它实际上是按位复制。但是,一旦函数返回,变量的编译器插入清理代码就会运行。它注意到该变量是非null的,因此它假设该变量中存在动态数组引用,并且该数组被清除。

使用 real 类型声明变量要好得多。它使您的生活更轻松编译器。

答案 1 :(得分:0)

要回答我自己的问题,没有直接的方法可以做到这一点。但由于我不轻易放弃解决方案:

http://www.cromis.net/blog/2013/02/tanyvalue-an-attempt-to-make-the-best-variable-data-container/

它基本上完成了Embarcadero或Borland多年前应该做的事情。