Tôi đang thử nghiệm với khả năng tự động gọi các thủ tục hoặc các hàm nằm trong một bảng chức năng. Các ứng dụng cụ thể là một DLL xuất khẩu một con trỏ đến một bảng chức năng cùng với thông tin về số lượng các đối số và các loại. Các ứng dụng máy chủ sau đó có khả năng thẩm vấn các DLL và gọi các chức năng. Nếu chúng là các phương thức đối tượng, tôi có thể sử dụng Rtti để gọi chúng nhưng chúng là các thủ tục và hàm bình thường. Các DLL có xuất con trỏ chức năng bình thường không đối tượng vì DLL có thể được viết bằng bất kỳ ngôn ngữ bao gồm C, Delphi, vvLàm thế nào để tự động gọi một thủ tục hoặc chức năng được đặt tên trong Delphi
Ví dụ, tôi có một kỷ lục đã kê khai và điền vào trong một DLL:
TAPI = record
add : function (var a, b : double) : double;
mult : function (var a, b : double) : double;
end;
PAPI = ^TAPI;
tôi lấy con trỏ đến kỷ lục này, khai báo là:
apiPtr : PAPI;
Giả sử tôi cũng có quyền truy cập vào tên của các thủ tục, số lượng các đối số và loại đối số cho mỗi mục trong hồ sơ.
Giả sử tôi muốn gọi hàm cộng. Con trỏ hàm để thêm sẽ là:
@apiPtr^.add // I assume this will give me a pointer to the add function
tôi giả sử không có cách nào khác ngoài việc sử dụng một số asm để đẩy các đối số cần thiết trên stack và lấy kết quả?
Câu hỏi đầu tiên, quy ước gọi điện thoại tốt nhất để khai báo quy trình là, cdecl là gì? Có vẻ dễ nhất để lắp ráp ngăn xếp trước cuộc gọi.
Câu hỏi thứ hai, có bất kỳ ví dụ trực tuyến nào thực sự thực hiện việc này không? Tôi đã xem qua http://www.swissdelphicenter.ch/torry/showcode.php?id=1745 (DynamicDllCall) mà gần với những gì tôi muốn nhưng tôi đơn giản như dưới đây, bây giờ nó trả về một con trỏ (EAX) cho kết quả:
function DynamicDllCall(proc : pointer; const Parameters: array of Pointer): pointer;
var x, n: Integer;
p: Pointer;
begin
n := High(Parameters);
if n > -1 then begin
x := n;
repeat
p := Parameters[x];
asm
PUSH p
end;
Dec(x);
until x = -1;
end;
asm
CALL proc
MOV p, EAX <- must be changed to "FST result" if return value is double
end;
result := p;
cuối;
nhưng tôi không thể làm cho nó hoạt động, nó trả về một giá trị cho các tham số đầu tiên thay vì kết quả. Có lẽ tôi có quy ước gọi sai hoặc có thể tôi hiểu sai cách lấy kết quả trong EAX.
tôi gọi DynamicDllCall như sau:
var proc : pointer;
parameters: array of Pointer;
x, y, z : double;
p : pointer;
begin
x:= 2.3; y := 6.7;
SetLength(parameters, 2);
parameters[0] := @x; parameters[1] := @y;
proc := @apiPtr^.add;
p := DynamicDllCall(proc, Parameters);
z := double (p^);
Bất cứ lời khuyên biết ơn nhận được. Tôi đánh giá cao rằng một số có thể cảm thấy đây không phải là cách người ta nên làm về điều này nhưng tôi vẫn tò mò nếu nó là ít nhất có thể.
Cập nhật 1 Tôi có thể xác nhận rằng chức năng thêm đang nhận được các giá trị chính xác để thực hiện việc bổ sung.
Cập nhật 2 Nếu tôi thay đổi chữ ký của thêm vào:
add : function (var a, b, c : double) : double;
và tôi gán kết quả cho c bên trong thêm, sau đó tôi có thể lấy câu trả lời đúng trong mảng tham số (giả sử tôi thêm một nhiều yếu tố hơn, 3 thay vì 2). Do đó, vấn đề là tôi hiểu sai cách các giá trị được trả về từ các hàm. Bất cứ ai có thể giải thích cách chức năng trả về giá trị và cách tốt nhất để lấy chúng?
Cập nhật 3 Tôi có câu trả lời. Tôi nên đoán. Delphi trả về các kiểu khác nhau thông qua các thanh ghi khác nhau. ví dụ như các số nguyên trả về qua EAX, tăng gấp đôi số tiền còn lại thông qua ST (0). Để sao chép ST (0) vào biến kết quả, tôi phải sử dụng "kết quả FST" thay vì "MOV p, EAX". Tôi ít nhất giờ tôi biết rằng có thể về nguyên tắc có thể làm được điều này. Cho dù đó là một điều hợp lý để làm là một vấn đề khác tôi phải nghĩ đến.
Có sử dụng để có một giới thiệu tốt đẹp để Delphi ASM tại www.delphi3000.com (bài viết/article_3766.asp), nhưng toàn bộ trang web đã biến mất ... –
Có lẽ tài liệu về [Quy trình và chức năng lắp ráp] (http : //docwiki.embarcadero.com/RADStudio/XE4/en/Assembly_Procedures_and_Functions) sẽ hữu ích. Xem chủ đề 'Kết quả Chức năng'. –
Không có nhiều ở đó và các tài liệu chính thức không phải là hữu ích khủng khiếp.Tuy nhiên, tôi đã ghép lại đủ thông tin từ: http://stackoverflow.com/questions/15786404/fld-instruction-x64-bit và http://www.guidogybels.eu/docs/Using%20Assembler%20in% 20Delphi.pdf – rhody