2011-01-31 12 views
7

Như một quy tắc chung, tôi đã phá vỡ rất nhiều bẫy thiết kế cổ điển khi sử dụng con trỏ bằng cách tận dụng các tham số Const (không được nhập) thay vì các kiểu mã hóa cứng. Điều này mang lại cho tôi lợi ích của tốc độ khi thực hiện các chức năng đồ họa tiên tiến trong khi để lại các chi tiết kỹ thuật cho trình biên dịch. Nó cũng đã làm cho nó dễ dàng để sử dụng cùng một mã trong Delphi và Free Pascal với những thay đổi tối thiểu. Tuy nhiên, tôi đã bắt đầu đặt câu hỏi này do câu lệnh vẫy của Embarcadero về sự tiến hóa của Delphi và nó là mô hình an toàn upcomming.Liệu các tham số const và công việc định kiểu như trước dưới Delphi 64bit?

Ví dụ, concider ví dụ sau:

Type TSomeDataProc = procedure (const aInput;var aOutput) of Object; 

(* Convert 8-bit pixel to 16-bit pixel *) 
Procedure TMyClass.ProcessSomeData08x565(Const aInput;var aOutput); 
var r,g,b: Byte; 
Begin 
    FPalette.ExportTriplets(Byte(aInput),r,g,b); 
    Word(aOutput):=(R SHR 3) SHL 11 or (G SHR 2) SHL 5 or (B SHR 3); 
End; 

(* Convert 16-bit pixel to 24-bit pixel *) 
Procedure TMyClass.ProcessSomeData565x888(Const aInput;var aOutput); 
Begin 
    With TRGBTriple(aOutput) do 
    Begin 
    rgbtRed:=(((word(aInput) and $F800) shr 11) shl 3); 
    rgbtGreen:= (((word(aInput) and $07E0) shr 5) shl 2); 
    rgbtBlue:= ((word(aInput) and $001f) shl 3); 
    end; 
End; 

Bây giờ chúng ta có hai thủ tục với tờ khai giống nhau, nhưng họ xử lý các pixeldata rất khác nhau. Điều này cho chúng ta lợi ích của việc sử dụng một bảng tra cứu để có được phương pháp "chuyển đổi" chính xác. Điều này nên được thực hiện trong một trong hai nhà xây dựng hoặc bất cứ nơi nào bitmap hình ảnh được phân bổ như sau:

Private 
FLookup: Array[pf8bit..pf32bit,pf8bit..pf32bit] of TSomeDataProc; 

Procedure TMyClass.Create; 
Begin 
    Inherited; 
    FLookup[pf8bit,pf16bit]:=ProcessSomeData08x565; 
    FLookup[pf16bit,pf24Bit]:=ProcessSomeData565x888; 
end; 

Bất cứ khi nào chúng ta cần phải chuyển đổi pixel chúng tôi chỉ đơn giản là tìm kiếm các phương pháp chính xác và sử dụng nó. Cú pháp vẫn giữ nguyên cho tất cả các thủ tục - vì vậy chúng tôi không phải lo lắng về "cách thức" mỗi quy trình hoạt động. Theo như lớp học của chúng tôi là có liên quan, tất cả họ đều giống nhau.

Procedure TMyClass.ConvertTo(aFormat:TpixelFormat); 
Begin 
// Get function for the correct pixel converter 
FConvertProc:=FLookup[CurrentFormat,aFormat]; 

//Use the pixel converter 
FConvertProc(GetSourcePixelAddr(x,y),GetTargetPixelAddr(x,y)); 
end; 

Câu hỏi đặt ra là: loại typecasting sẽ (ví dụ: Const để Byte hoặc bất kỳ bản ghi loại được xác định) tồn tại dưới 64bit? Cá nhân tôi không thể hiểu tại sao không, nhưng Embarcadero đã mơ hồ về mô hình "an toàn" mới và sử dụng con trỏ, vì vậy tôi thấy khó có thể bảo vệ mã của mình trong tương lai.

+1

Tôi không thể cho tôi thấy lý do tại sao bạn viết nó theo cách đó chứ không phải: 'ProcessSomeData (Const aInput) : Byte; var aOutput: Word); ' –

+1

Bạn không chuyển con trỏ tới mã ví dụ đó, phải không? Ngoài sự tò mò, có gì sai với hệ thống kiểu tích hợp, tốc độ con trỏ là gì? –

+0

@Sertac Tốc độ giống nhau ở đây. Có một sự khác biệt tinh tế giữa một tham số var typeless và một tham số không kiểu const và một con trỏ chung: một tham số không kiểu const không được sửa đổi, trong khi một con trỏ luôn có thể được sửa đổi. Và bằng cách sử dụng một var không cần thiết như vậy có thể tránh gõ một số^ký tự trong mã của bạn: PWord (aOutput) ^: = 13 chẳng hạn. Trình tạo được tạo ra sẽ giống như từ (aOutput): = 13. –

Trả lời

3

Vì các thủ thuật như vậy được sử dụng trong RTL, tôi không thấy không dùng tham số var hoặc const typeless mà không có nhiều ngắt mã.

Embarcadero cố gắng hết sức để duy trì khả năng tương thích ngược nhiều nhất có thể.

Chúng thậm chí nên bao gồm nội tuyến asm trong trình biên dịch 64 bit, sau khi lần đầu tiên thực hiện một số thông báo về việc sử dụng bộ lắp ráp bên ngoài.

Và sửa đổi như vậy sẽ không có liên quan gì đến mô hình 64 bit, trong khi trình biên tập x86-64 là một đoạn mã mới để viết.

Vì vậy, bạn nên đăng câu hỏi này của nhóm tin chính thức của Embarcadero, nhưng tôi nghĩ bạn không phải lo lắng về điều này.

+0

Allen Bauer đã được báo cáo trong một podcast gần đây tại http://www.delphi.org rằng lắp ráp nội tuyến sẽ được hỗ trợ (với một số hạn chế) trong trình biên dịch 64 bit Delphi. –

+0

@Remy Vâng, đây là những gì tôi đã nói. Một động thái tốt. Đã có một số loại hoảng loạn trong các nhóm tin khi họ nói về việc loại bỏ các bộ lắp ráp nội tuyến trong trình biên dịch 64 bit Delphi. Phiên bản "Starter" mới cũng là một cái gì đó tốt. Nhưng khi tôi nghe Allen nói về tương lai của Delphi, và một người thu gom rác, tôi lại hoảng sợ. ;) –

1

Lưu ý rằng FPC đã thay đổi tham số CONST, mặc dù không phải trong trường hợp này.

Đối với trường hợp thông thường, CONST không được đảm bảo bằng tham chiếu nữa cho tất cả các quy ước gọi điện, nhưng tuân theo bất cứ điều gì ABI tương ứng chỉ định. Một kiểu tham số mới, CONSTREF được đảm bảo bằng tham chiếu.

Giống như tất cả các sự cố tương thích, đó là vấn đề trong TP/Delphi CONST luôn là ref, nhưng TP/Delphi cũng luôn là x86.

Trong số các hàm khác, tất cả các hàm STDCALL đều thay đổi, ví dụ: Tôi không biết.QueryInterface:

http://wiki.freepascal.org/User_Changes_Trunk#IInterface.QueryInterface.2C_._AddRef_and_._Release_definitions_have_been_changed

Lý do là nhiều hay ít mà trong những trường hợp này, thông tin x86 ABI bước vào giao diện chung, một cái gì đó mà không phải là cross-kiến trúc tương thích. Vì vậy, người ta phải đoán nếu nó là một phần của ngôn ngữ, hoặc một phần của việc thực hiện x86 của ngôn ngữ.

Lưu ý rằng IUnknown cũng được sử dụng trên các nền tảng khác, ví dụ: Delphi cũng có thể nhấn các snags như vậy, nhưng tôi nghĩ chúng chủ yếu sẽ thực hiện các chức năng/phương thức với các yêu cầu quy ước rõ ràng, bởi vì người ta có thể thay đổi quy ước nội bộ cho phù hợp với nhu cầu, nhưng thực tế không thể thay đổi phần còn lại của thế giới ((XP) COM hoặc các thư viện C (++) hiện có) cho phù hợp với mã hiện tại trong Delphi

Các vấn đề liên quan