2010-06-19 71 views
0

我正在嘗試創建一個稍後將在Inno安裝程序中使用的DLL。 我設法創建使用Pelles作爲IDE一個DLL,用以下代碼:創建/調用DLL的問題

#include <windows.h> 

__declspec(dllexport) int sumT(){ 
    return 2; 
} 

然後我調用的DLL映射到創新安裝的功能,使用以下Delphi代碼:

function Hellow() : Integer ; 
external '[email protected]:yyy.dll stdcall'; 

它按預期工作,返回2.我也可以從rundll32.exe調用它 - 如果我在DLL中添加一個MsgBox,它會出現,證明一切都按預期工作。

現在,當我嘗試將值傳遞給DLL,這樣的問題開始 - 例如:

#include <windows.h> 

__declspec(dllexport) int sumT(int sumTah){ 
    return sumTah; 
} 

它停止工作! 在Inno Setup的,我給我的留言:

「運行時錯誤(在1:0)」

如果我嘗試RUNDLL32.EXE,我得到:

錯誤yyy.dll

欠缺的出入:SUMT

我不會在這裏粘貼Delphi代碼,因爲我虛擬了所有的東西,與C代碼一樣的東西,我試着使用__stdcall來代替,聲明參數爲INT,UINT ...和其他我忘記的東西。

我也查了MSDN,但找不到有關這個特定問題的任何東西。

那麼,任何人都可以幫忙嗎?

感謝

編輯:我在編譯C,所以不需要 「外部」。

回答

2

,導出的名稱可能不匹配,你在想什麼樣子。使用DLL上的dumpbin.exe/exports來查看實際導出的名稱。使用extern「C」來抑制名稱變形。

此外,你必須聲明這個函數__stdcall,這就是你的Delphi聲明所說的。缺省值是__cdecl。當你開始傳遞參數時會失敗。

+0

感謝您使用dumpbin.exe的提示 事實證明,該函數導出爲「_sumT @ 4」 我在編譯器中發現了一個選項「Undecorate Exported stdcall functions」(在Project options - > Compiler中)。這應該做到這一點。順便說一句__stdcall似乎沒有工作。 – Rolf 2010-06-19 09:06:35

1

如果使用C++編譯器進行編譯,函數名稱會發生​​錯位,以便它包含有關參數的數據。解決的辦法是做這樣的事情:

extern "C" __declspec(dllexport) int myfn();

,然後引用它作爲_myfn。 extern "C"告訴編譯器不要調整函數名稱。這不適用於模板化函數,類或重載函數。

+0

謝謝。我忘了提及我已經在C編譯,所以不需要「extern」(AFAIK)。但是函數不會被導出爲_sumT @ 4,所以你對下劃線是正確的。我通過設置編譯器選項(「Undecorate Exported stdcall functions」)解決了這個問題。 – Rolf 2010-06-19 09:08:04

+1

stdcall函數將堆棧佔用的字節數加到最後(這裏是@ 4);使它們未修飾可能會導致堆棧損壞問題。你可能想用cdecl調用約定標記它,它總是將調用留作'_sumT'。 – reece 2010-06-19 11:31:27

1

__declspec(dllexport)的INT SUMT(INT sumThah){
返回sumTah;

看起來像一個錯字或您的錯誤....

+0

謝謝!我修正了這一點。 – Rolf 2010-06-19 08:51:32