2010-03-11 24 views
5

3 loại này rất giống nhau ...TArray <Byte> VS TBytes VS PByteArray

TArray là phiên bản chung của TB. Cả hai có thể được đúc thành PByteArray và được sử dụng làm bộ đệm cho các cuộc gọi đến Windows API. (với các hạn chế tương tự như chuỗi để Pchar).

Điều tôi muốn biết: Hành vi này "theo thiết kế" hay "Theo triển khai". Hay cụ thể hơn, nó có thể phá vỡ trong bản phát hành trong tương lai không?

// Chỉnh sửa Như đã nêu bên dưới ... Điều tôi thực sự muốn biết là: Điều này có an toàn khi nhập TBytes (hoặc TArray) vào PByteArray hay không. liên quan. (Hoặc có thể AnsiString để PAnsiChar là một ví dụ tốt hơn^_ ^)

Trả lời

3

Đơn giản chỉ cần đặt, một mảng byte là một mảng byte, và miễn là định nghĩa của byte và mảng không thay đổi, điều này đã thắng không thay đổi. Bạn được an toàn để sử dụng nó theo cách đó, miễn là bạn chắc chắn để tôn trọng các giới hạn mảng, kể từ khi đúc nó ra khỏi các loại mảng Delphi của nullifies kiểm tra giới hạn của bạn.

EDIT: Tôi nghĩ rằng tôi thấy những gì bạn đang yêu cầu tốt hơn một chút.

Không, bạn không nên truyền tham chiếu mảng động tới con trỏ mảng kiểu C. Bạn có thể lấy đi với nó bằng dây bởi vì trình biên dịch giúp bạn ra một chút.

Tuy nhiên, bạn có thể tạo con trỏ tới phần tử 0 của mảng động với con trỏ mảng kiểu C. Điều đó sẽ hoạt động và sẽ không thay đổi.

+0

Thực ra, bạn sai ... một "mảng byte" không phải là một mảng byte ... Đó là một con trỏ tới mảng động của byte được tính tham chiếu và độ dài được quản lý (Khá giống như chuỗi). Những gì tôi muốn biết là: Đây có phải là an toàn để typecast TBytes (hoặc TArray ) để PByteArray vì nó là để typecast String để PChar như xa như khả năng tương thích về phía trước là có liên quan. –

+0

Một "mảng Byte" ** là một mảng byte. Điểm khác biệt duy nhất là nó được hiển thị với thời gian chạy chủ yếu dưới dạng * loại tham chiếu *, chứ không phải là một loại giá trị * * (như trong trường hợp của một mảng tĩnh). Trình biên dịch biết điều này tất nhiên và sẽ (ok, nên) chăm sóc typecast cho bạn theo cách tương tự với String <> PChar (thường được gọi là "trình biên dịch ma thuật" - tức là tạo mã dựa trên trình biên dịch nhận thức được nội bộ của chính nó). – Deltics

+0

@Ken: OK, tôi hiểu ý của bạn là gì. Chỉnh sửa trả lời của tôi. –

1

Hai trong số các loại đó giống nhau (giống hệt nhau trên thực tế). Thứ ba là không.

TArray được khai báo là "Array của Byte", như là TBytes. Tuy nhiên, bạn đã bỏ lỡ một loại rất phù hợp hơn, TByteArray (loại được tham chiếu bởi PByteArray).

Là một con trỏ đến TByteArray, PByteArray đang nói hoàn toàn là một con trỏ đến một mảng byte tĩnh, không phải là một mảng động (mà các loại mảng byte khác tất cả đều). Nó được gõ theo cách này để cho phép tham chiếu đến các offset từ con trỏ cơ sở đó bằng cách sử dụng một chỉ số nguyên. Và lưu ý rằng việc lập chỉ mục này được giới hạn trong 2^15 phần tử (0..32767). Đối với độ lệch tùy ý byte (> 32767) từ một số con trỏ cơ sở, một PByteArray là không tốt:

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; 

tức là đúc một mảng của Byte hoặc một TArray đến một PByteArray được khả năng sẽ dẫn đến các vấn đề trong đó mảng có> 32K phần tử (và con trỏ được chuyển tới một số mã cố gắng truy cập tất cả các phần tử). Việc truyền tới một con trỏ không định hướng tránh được điều này tất nhiên (miễn là "người nhận" của con trỏ sau đó xử lý truy cập vào tham chiếu bộ nhớ bằng con trỏ một cách thích hợp).

NHƯNG, không điều nào trong số này có khả năng thay đổi trong tương lai, nó chỉ là hậu quả của các chi tiết triển khai từ lâu đã được áp dụng trong lĩnh vực này.Sự ra đời của một tuyên bố kiểu generic chung loại cú pháp là kipper rouge.

+0

Mặt khác, nếu cần, giới hạn 32767 có thể được bỏ qua bằng cách redeclaring cục bộ kiểu này theo cách này. loại PByteArray =^TByteArray; TByteArray = mảng [0..MaxInt - 1] của Byte; –

+0

"Kipper rouge"? Điều đó nghĩa là gì? –

+0

Xin lỗi - Kipper Rouge = "Red Herring" :) – Deltics