我正在嘗試動態調用駐留在函數表中的過程或函數的功能。特定的應用程序是一個DLL,它將一個指向函數表的指針與關於參數和類型數量的信息一起導出。宿主應用程序然後有能力詢問DLL並調用函數。如果它們是對象方法,我可以使用Rtti來調用它們,但它們是正常的過程和函數。該DLL擁有自營出口正常的函數指針不是對象,因爲DLL可以寫成包括C,德爾福等任何語言如何動態調用Delphi中的命名過程或函數
例如,我有一個創紀錄的聲明,並在DLL中填寫:
TAPI = record
add : function (var a, b : double) : double;
mult : function (var a, b : double) : double;
end;
PAPI = ^TAPI;
我檢索指向此記錄,聲明如下:
apiPtr : PAPI;
假設我也有機會獲得本程序的名字,論點和論據類型記錄中的每個條目數量。
假設我想調用add函數。函數指針增加將是:
@apiPtr^.add // I assume this will give me a pointer to the add function
我假設有沒有其他的方法只需要使用一些ASM推棧所需的參數並檢索結果?
第一個問題,聲明該過程的最佳調用約定是什麼,cdecl?看起來最容易在通話之前組裝堆棧。
第二個問題,是否有任何實際的在線實例呢?我碰到http://www.swissdelphicenter.ch/torry/showcode.php?id=1745(DynamicDllCall),這是接近我想要什麼,但我簡化爲以下,現在返回一個指針(EAX)的結果:
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;
末;
但我不能得到它的工作,它返回的第一個參數,而不是結果的值。也許我的調用約定錯了,或者我誤解了如何在EAX中檢索結果。
我打電話DynamicDllCall如下:
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^);
任何建議感激地接受。我明白,有些人可能會覺得這不是我們應該這樣做的方式,但如果至少有可能,我仍然很好奇。
更新1我可以確認add函數獲得正確的值來進行添加。
更新2如果我改變增加的簽名:
add : function (var a, b, c : double) : double;
,我把結果賦給C內添加,然後我可以檢索參數數組中的正確答案(假設我想補充一個更多元素,3而不是2)。因此,問題是我誤解了函數返回值的方式。任何人都可以解釋函數如何返回值以及如何最好地檢索它們?
更新3我有我的答案。我應該猜到了。 Delphi通過不同的寄存器返回不同類型。例如整數通過EAX返回,另一方面通過ST(0)返回。要將ST(0)複製到結果變量,我必須使用「FST結果」而不是「MOV p,EAX」。至少我現在知道原則上可以這樣做。無論是明智的做法,還是我現在必須思考的另一個問題。
在德爾福ASM網站www.delphi3000.com(articles/article_3766.asp)中曾經有過不錯的介紹,但是整個網站現在都不存在了... –
也許關於[Assembly Procedures and Functions](http ://docwiki.embarcadero.com/RADStudio/XE4/en/Assembly_Procedures_and_Functions)會有所幫助。請參閱「功能結果」主題。 –
這裏沒有太多的東西,官方文檔也不是很糟糕。然而,我拼湊在一起足夠的信息: http://stackoverflow.com/questions/15786404/fld-instruction-x64-bit 和 http://www.guidogybels.eu/docs/Using%20Assembler%20in% 20Delphi.pdf – rhody