2016-03-23 40 views
6

Tôi đang cố gắng tìm hiểu xem có cách nào để làm những việc tương tự như các tính năng RTTI cải tiến của Delphi.FreePascal RTTI. Có cách nào để gọi phương pháp?

Theo tôi biết FPC không cung cấp tính năng RTTI xuất hiện ở Delphi kể từ Delphi 2010. Nhưng tôi muốn tìm một số cách để thực hiện một vài thủ thuật trong thời gian chạy.

Sử dụng typinfo đơn vị trong FPC tôi có thể làm những việc như:

  • get Object công bố danh sách bất động sản - qua getPropList từ typinfo đơn vị;
  • nhận/đặt giá trị của thuộc tính đã xuất bản của đối tượng - qua GetPropValue(...): Variant/SetPropValue(...Value: Variant);
  • tải phương thức đã xuất bản - qua MethodAddres;

Nhưng tôi đã không tìm thấy một cách để làm những việc như:

  • phương pháp gọi;
  • nhà xây dựng cuộc gọi hoặc tạo Đối tượng;

Cập nhật: vấn đề với nhà thầu là giống như các phương pháp một - Tôi muốn có một cách để vượt qua params khác nhau trong đó:

// concept of code 
type 

TClass = class of TObject; 

TMyClass1 = class 
    public 
    constructor Create(Param1: Integer; Param2: string); override; 
    end; 

TMyClass2 = class 
    public 
    constructor Create(ObjectParam: Object); override; 
    end; 

TParams = array of Variant; 

var 
Classes: array of TClass 
Instances: array of Object; 
ParamArray: array of TParams; 

... 

For I := 0 to Count-1 do 
begin 
    LocalConstructor := @(Classes[I].Create); 
    Instances[I] := CallConstructor(LocalConstructor, ParamArray[I]); 
end; 

Vì vậy, tôi cần phải gọi constructor mà không biết chữ ký của mình.

Vì vậy, vấn đề của tôi là gọi phương thức của đối tượng và chuyển một số tham số cho nó. Nó có thể trông giống như function CallMethod(Instance: Object; MethodName: String; Params: array of Variant): Variant;

Nếu tôi không nhầm nó có thể được giải quyết qua Delphi 2010+ RTTI. Nhưng trước khi sử dụng RTTI cải tiến của Delphi tôi muốn hiểu là nó có thể trong FPC.

Nói cách khác, vấn đề hiện tại của tôi là chuyển đối số cho một thường trình. Tôi biết nó có thể được thực hiện bằng chương trình này:

type 
    TmyProc = procedure CallMe(x: byte); 
... 
    var proc: TmyProc; 
... 
    proc := pointerToFunc^; 
    proc(0); 

Nhưng tôi cần phải thực hiện nó mà không biết đếm và loại thông số (trong thời gian biên dịch).

Có một vài liên kết liên quan đến chủ đề:

Delphi: Call a function whose name is stored in a string

http://www.swissdelphicenter.ch/torry/showcode.php?id=1745

Bài báo thứ hai (http://www.swissdelphicenter.ch/torry/showcode.php?id=1745) mô tả một cách để vượt qua đối số cho một thói quen nhập khẩu từ DLL theo tên. Đó là gần như tôi cần tôi giả sử. Nhưng tôi không chắc cách đó là đáng tin cậy.

Có thể có bất kỳ thư viện nào triển khai những thứ này bằng cách sử dụng đơn vị typinfo "cũ" (không có đơn vị RTTI)?

Ngoài ra tôi quan tâm đến một cách để tạo một số loại trình xử lý sự kiện phổ quát - các thủ tục có thể được gán cho các sự kiện khác nhau (với các bộ tham số khác nhau), ví dụ::

procedure myEventHandler(params: array of variant); 
... 
Button.OnClick := myEventHandler; 
Button.OnMouseMove := myEventHandler; 

là điều này có thể? Hoặc ít nhất một cái gì đó tương tự như nó?

Trả lời

5
  1. Bạn có thể gọi các phương thức, thậm chí không được xuất bản, sử dụng MethodAddress, nhưng tùy thuộc vào bạn để đảm bảo danh sách đối số chính xác.
  2. Bạn có thể gọi hàm tạo bằng cách sử dụng metaclasses (tham chiếu lớp), ví dụ về nó có thể được nhìn thấy trong TCollection: bạn vượt qua lớp của mục bộ sưu tập của bạn lúc chạy và sau đó nó có thể được tạo khi cần. Bằng cách định nghĩa lớp trừu tượng với hàm tạo ảo (và có thể là trừu tượng), bạn có thể đưa ra danh sách đối số mà bạn muốn, ví dụ: here.
  3. AFAIK không có cách nào để xác định danh sách đối số khi chạy, nhưng nếu bạn thiết kế cả hai phương thức để gọi và người gọi, có nhiều cách bạn có thể thực hiện hành vi tương tự.

Ví dụ, bạn chuyển mảng mở biến thể (Array of const), vì nó được thực hiện trong Định dạng(), vì vậy số đối số và loại đối số của nó có thể thay đổi. Nhưng thậm chí có một và chỉ con trỏ làm đối số, bạn chắc chắn có thể vượt qua bao nhiêu tùy thích, tất cả những gì bạn cần làm là đưa ra một số lớp mà nó sẽ dẫn dắt.

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