2012-02-22 56 views
2

我完全是pascal的新手。 我想在免費的pascal中的.dll文件中調用我的函數,當我運行該項目時出現以下錯誤:免費Pascal找不到dll的入口點

過程入口點GetProcAddress無法位於動態鏈接庫HNLib.dll中。

這裏是代碼:

Program Test; 
function GetProcAddress : Integer; cdecl; external 'HNLib.dll'; 
function GetProcAddress : Single; cdecl; external 'HNLib.dll'; 
procedure GetProcAddress(X : Single); cdecl; external 'HNLib.dll'; 
procedure GetProcAddress; cdecl; external 'HNLib.dll'; 
begin 
    GetProcAddress(5.5); 
    readln; 
end. 

的.pas文件和DLL是在一個目錄。

請幫幫我!

+0

顯而易見的第一個問題:在您的DLL中是否存在*假設*是一個名爲'GetProcAddress'的函數? – 2012-02-23 23:01:20

回答

7

GetProcAddress是不是你認爲它是什麼;它的目的是在DLL中找到命名的過程或函數,並返回該函數的地址,以便從代碼中調用該函數。您必須首先使用LoadLibrary將動態鏈接庫(DLL)加載到內存中,然後將該句柄傳遞給該DLL,作爲GetProcAddress的第一個參數以及要將其地址作爲第二個參數的函數的名稱。如果可以在DLL中找到該函數,則返回地址,並且可以使用該地址來調用該函數。

(此外,GetProcAddress是相當Windows專用的,並且多數在WinAPI的功能stdcall而不是cdecl。除非你有文件說,函數使用cdecl調用約定,你應該使用stdcall。 )

您的使用條款中至少還需要Windows單位,因爲這是宣佈GetProcAddressLoadLibrary的地方。

有關更多信息,請參閱關於LoadLibraryGetProcAddress的WinAPI文檔。

對於一個開始的程序員,你可能會發現使用函數的靜態鏈接而不是動態鏈接(使用GetProcAddress得到的)更容易。靜態鏈接的一個例子是(未經測試!!! - 只是一個快速的代碼示例,因爲我沒有「HNLib.DLL」來鏈接):

// Your Dll import unit 
unit MyDllProcs; 

interface 

    function GetIntCalcResult(const IntVal: Integer); 

implementation 

    function GetIntCalcResult(const IntVal: Integer); stdcall; external 'HNLib.dll'; 

end. 

// Your own app's code 
program Test; 

interface 

    uses MyDllProcs; 

implementation 

function DoSomethingWithDll(const ValueToCalc: Integer): Integer;   
begin 
    Result := GetIntCalcResult(ValueToCalc); 
end; 

begin 
    WriteLn('DoSomethingWithDll returned ', DoSomethingWithDll(10)); 
    ReadLn; 
end. 

注意,當靜態鏈接DLL功能,如這個,你的DLL必須在你的應用程序啓動時可用,並且該函數必須包含在該DLL中;如果沒有,你的應用程序將不會加載。

此外,請注意,您通常不能在DLL中具有多個具有相同名稱的函數,因爲沒有可用的信息來確定加載完成時要加載哪一個函數。每個應該有一個單獨的,不同的名稱或加載可能會失敗。

+0

+1我不明白你爲什麼得到-1,這是完美的解釋,但我會從「程序」代碼拆分「myddlprocs」單元代碼,否則它可能會變得更難理解,但除此之外,這是完美的! – ComputerSaysNo 2012-02-23 08:50:46

+1

+1不知道爲什麼任何人可以downvote這一點。我唯一的意見是第二段暗示人們可能會猜測調用約定。人們應該始終確定調用約定是什麼。而一個小小的挑逗,你稱之爲靜態鏈接,正式被稱爲隱式鏈接,但我相信每個人都厭倦了我指出這一點。 – 2012-02-23 09:19:34

+0

謝謝。 Dorin,我把它們分成了兩個獨立的單元(單元MyDllProcs和程序測試)。大衛,我接受nitpick,但我認爲這兩個術語都是可以接受的(德爾福文檔的年齡被稱爲靜態和動態鏈接到DLL;我不知道他們是現在這樣寫的,但是對於那些誰與D/C++ Builder一直熟悉的術語)。我也不知道downvote,但我有懷疑(通常的)。 – 2012-02-23 11:55:32