2009-07-13 25 views
0

这是我的功能:如何获取Result的地址?

class function TCelebrity.ReadArray<T>(length:integer): byte; 
var b:pointer; 
begin 
    b := @Result; 
    if IndexR + SizeOf(T) * length > High(DataRead) + 1 then 
    raise Exception.Create('error'); 
    Move(DataRead[IndexR],b,SizeOf(T) * length); 
    Inc(IndexR,SizeOf(T) * length); 
end; 

IndexR是整数,DATAREAD是字节的阵列。

该函数从IndexRef(position)的DataRead读取长度。在我的情况下,它在读取位置的4个字节0

的问题是,我想打电话这样的功能:

ar[5] := c.ReadArray<byte>(4); or - @ar[5] := c.ReadArray<byte>(4); //ar is Byte array 

我知道我可以创建一个参数用指针字节数组,但我想知道是否可以这样做?

编辑:

我也尝试该功能,它改变仅AR [5]和它应该从AR [5]至AR改变[8]。

class function TCelebrity.ReadArray<T>(length:integer): byte; 
var b:^byte; i:integer; 
begin 
    b := @Result; 
    for I := 0 to length - 1 do 
    begin 
    b^ := DataRead[IndexR]; 
    Inc(IndexR); 
    Inc(b); 
    end; 
end; 

第二个例子应该工作。如果AR [0]被放置在随后40万$ AR [1]应放置在$ 400001等。本是我的功能是什么,但不幸的是它仅适用于第一个参数。

回答

6

首先,你的声明指定它只返回一个字节,而不是一个字节数组,而且肯定不是一个指向数组的指针。在目前的状态下,你会覆盖堆栈并崩溃。您可以使用无类型的“var”参数而不是函数结果。

class procedure TCelebrity.ReadArray<T>(length:integer; var Result); 
var b:pointer; 
begin 
    b := @Result; 
    if IndexR + SizeOf(T) * length > High(DataRead) + 1 then 
    raise Exception.Create('error'); 
    Move(DataRead[IndexR],b^,SizeOf(T) * length); 
    Inc(IndexR,SizeOf(T) * length); 
end; 

然后调用它像这样:

c.ReadArray<byte>(4, ar[5]); 

然而,这仍然是很危险的。您必须必须确保在数组'ar'的给定偏移量处有足够的剩余空间存储您打算写入的字节。

+0

在这段代码中我真的不明白的是为什么有一个移动到b而不是b ^?我错过了,还是复制/粘贴了原始的味精? – 2009-07-14 11:51:31

1

在第一个功能,如果你移动到b,你移动到鼠标指针导致的存放处(B),不会导致(pansichar(B)^)

而且你DATAREAD的定义是含糊不清的。 “字节数组”可以是一个动态数组(其中high()毫无意义)作为开放数组(其中high()确实有意义)。

表达式中的一些括号也伤害了任何人,但我不知道这是否是问题。

+0

在这两种情况下,当我调用它时,我用静态数组成员调用它。像ar [4]。它的静态,但大小不会总是4,因为它在这个例子中。 – 2009-07-13 14:05:24