2010-03-11 103 views
5

這些3種類型很相似......在tarray <Byte> VS TB的VS PByteArray

在tarray是太字節的通用版本。 兩者都可以被轉換爲PByteArray並用作調用Windows API的緩衝區。 (與Pchar的字符串具有相同的限制)。

我想知道的是:這種行爲是「按設計」還是「按實施」。或者更具體地說,它可以在未來的版本中打破嗎?

//編輯 如前所述低... 我真正想知道的是:這是爲安全的類型轉換太字節(或在tarray),以PByteArray,因爲它是類型轉換字符串爲遠PCHAR向前兼容性關心。 (或者,也許AnsiString到PAnsiChar是一個更好的例子^ _ ^)

回答

3

簡而言之,一個字節數組是一個字節數組,只要字節和數組的定義不變,也不會改變。只要確保尊重數組邊界,就可以安全地使用它,因爲將它從Delphi的數組類型中刪除會使邊界檢查無效。

編輯:我想我看到你現在要求的更好一點。

不,您不應該將動態數組引用轉換爲C樣式的數組指針。你可以用字符串來避開它,因爲編譯器可以幫助你一點點。

但是,您可以執行的操作是將指向動態數組的元素0的指針轉換爲C樣式的數組指針。那工作,並不會改變。

+0

實際上,你錯了......一個「字節數組」不是一個字節數組...它是一個指向字節的動態數組的指針,它是引用計數和長度管理的(非常像字符串)。我想知道的是:就向前兼容性而言,這對於將類型字符串轉換爲PChar是否對於PByteArray類型TBytes(或TArray )是安全的。 – 2010-03-11 19:23:29

+0

「字節數組」**是**字節數組。唯一的區別是,它表現爲運行時主要作爲*引用類型*,而不是*值類型*(如靜態數組的情況)。當然,編譯器知道這一點,並且將(以及應該)以類似於String <> PChar(通常稱爲「編譯器魔術」)的相同方式來處理類型轉換(即通常依賴於編譯器的代碼生成意識到它是自己的內部)。 – Deltics 2010-03-11 19:38:35

+0

@Ken:好的,我明白你的意思了。編輯我的回覆。 – 2010-03-11 19:48:28

1

其中兩種類型是相似的(事實上相同)。第三不是。

在tarray被聲明爲 「陣列字節的」,因爲是TB的。您錯過了另一個非常相關的類型,但是,TByteArrayPByteArray引用的類型)。

作爲一個指針TByteArrayPByteArray,嚴格來說是一個指向一個靜態字節數組,而不是一個動態陣列(其中其它字節數組類型都是)。它以這種方式輸入,以便允許使用整數索引引用該基址指針的偏移量。並且請注意,此索引僅限於2^15元素(0..32767)。用於從一些基指針任意字節偏移(> 32767),一個PByteArray是沒有好處:

var 
    b: Byte; 
    ab: TArray<Byte>; 
    pba: PByteArray; 
begin 
    SetLength(ab, 100000); 
    pba := @ab;    // << No cast necessary - the compiler knows (magic!) 
    b := pba[62767];  // << COMPILE ERROR! 
end; 

即鑄造陣列字節的或在tarrayPByteArray潛在地要導致數組有> 32K個元素的問題(並且指針被傳遞給一些嘗試訪問所有元素的代碼)。投射到一個無類型的指針當然可以避免這種情況(只要指針的「接收者」然後通過指針恰當地處理對內存引用的訪問)。

但是,這些都不會在未來發生變化,這只是實施細節早就應用於此領域的一個後果。引入語法加糖的泛型類型聲明是笛子紅

+0

在一方不是,如果需要出現,32767的限制可以通過以這種方式在本地重新聲明類型來繞過。 類型 PByteArray =^TByteArray; TByteArray = Byte的數組[0..MaxInt - 1] – 2010-03-11 20:48:37

+0

「胭脂紅」?那是什麼意思? – 2010-03-11 21:19:39

+0

對不起 - Kipper Rouge =「紅鯡魚」:) – Deltics 2010-03-12 00:42:52