2010-08-23 85 views
1

我正在導入一個innosetup安裝腳本中的C++ DLL。該DLL的代碼如下:將DLL導入Inno-Setup的問題

void __stdcall SetFbParam(char *dbFileName,char *dbTableName,char *dbParamName,char *dbParamValue){ 
//of no use here and doesn't change anything} 

在Innosetup,我把它用

procedure FBset(dbFileName,dbTableName,dbParamName,dbParamValue: String;); 

external '[email protected]:MyDll.dll stdcall setuponly';

但是,我總是啓動安裝程序的過程中得到一個運行時錯誤,說是進口它不能導入我的dll。我嘗試了各種調用約定,但總是失敗。 如果它非常重要,我使用UAC運行Win7 x64(安裝程序請求權限提升並在此之後崩潰)。

確切信息是:
錯誤
運行時錯誤(在-1:0):
無法導入
DLL:C:\用戶\ Nevod \應用程序數據\本地\ TEMP \是-6LOEC.tmp \ MyDll.dll

該DLL在那裏。

謝謝!

+0

不要讓我們猜測運行時錯誤消息。 – 2010-08-23 17:26:45

+0

確切信息是: 錯誤 運行時錯誤(在-1:0): 無法導入 DLL:C:\用戶\ Nevod \應用程序數據\本地\ TEMP \是-6LOEC.tmp \ MYDLL.DLL 的dll在那裏。 – nnevod 2010-08-23 17:34:45

+0

而你正在導入的功能也被實際導出? – deemok 2010-08-26 20:39:42

回答

5

MyDll.dll 32位?

MyDll.dll是否依賴於同一目錄中的任何其他DLL?如果是這樣,則需要在「MyDll.dll」之後列出這些DLL的名稱,以確保它們在提取之前被提取,並且您可能還需要「loadwithalteredsearchpath」選項。從help例如:

procedure ADllFunc(hWnd: Integer; lpText, lpCaption: String; uType: Cardinal); 
external '[email protected]:A.dll,B.dll stdcall loadwithalteredsearchpath'; //A.dll depends on B.dll 
3

(我知道這是舊的,但可能其他一些命中這一個了)

最大的可能是函數的名稱在C++ DLL的錯位。我有同樣的問題,我可以通過重新編譯dll來解決它。總之:

如果從C++類似出口:

void __stdcall foo() 

,你會得到所謂的(Visual Studio中)的函數:

[email protected]@YGXXZ 

爲了避免名稱重整你應該使用出口「C 「指令。例如(Visual Studio中)

extern "C" __declspec(dllexport) void __stdcall foo() 

但是我發現,Visual Studio將繼續裂傷和你喜歡的東西:

[email protected] 

的唯一辦法,我能得到乾淨的名字在這裏解釋: C++ DLL Export: Decorated/Mangled names

而罪魁禍首確實是__stdcall。如果您從聲明中刪除是:

extern "C" __declspec(dllexport) void foo() 

你將再次得到一個乾淨的出口,即使沒有DEF文件。IMO應該足夠好,因爲上面的代碼聲明瞭一個「C」導出函數,而C的默認調用約定是stdcall。但我沒有時間和處置來驗證這一點,因爲添加DEF文件比導航asm代碼和檢查堆棧指針要容易得多:)

+0

謝謝@Yalos爲我解決了這個問題! – yairchu 2014-03-05 14:32:35

+0

你是一個滋養者,我永遠不會猜到stdcall是問題。 – caesay 2016-05-14 08:11:36

1

爲了在InnoSetup的[代碼]部分中使用DLL,請確保:

  • DLL在32位模式(即使安裝程序是專爲64位和64位模式下運行)
  • 導出函數有 extern "C" __declspec(dllexport) 修改
  • 使用cdecl調用約定,因爲STDCALL軋液名稱( http://msdn.microsoft.com/en-us/library/zxk0tw93.aspx)。當然,可以在InnoSetup import語句中指定mangled名稱。但使用cdecl似乎更容易
+0

*「請使用cdecl調用約定,因爲stdcall損壞了名稱」*,請您詳細說明一下嗎? – TLama 2015-03-14 11:39:28

+0

我不知道爲什麼,我沒有時間玩它,但由於某些原因,使用stdcall編譯的DLL導出的名稱如下所示:'_function @ 8'編譯相同的DLL只是改變**整體調用項目**的約定來cdecl將導出的名稱更改爲'function'。我已經使用VS2010進行了測試 – rkudinov 2015-03-15 12:35:07

+0

你遇到過所謂的名字混亂,但這不是說明你做了什麼的理由,我想。我相信你可以[停止VS這樣做](http://stackoverflow.com/q/1467144/960757)。 – TLama 2015-03-15 12:46:33