2009-07-13 52 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