2011-05-09 44 views
2

從一個c應用程序(VS2008,Win)中,我調用Borland的Delphi中編寫的dll函數。該函數的工作原理,但每次調用後,我得到這個錯誤:「ESP的價值沒有妥善保存在函數調用[...]」這意味着我的調用約定是錯誤的。我不知道Delphi和我沒有完整的DLL的代碼,但我相信這是德爾福功能:Win VS2008調用約定:來自c的Delphi dll

function translate(file1, file2: PChar):PChar; stdcall; 
    ... 
    Result:=PChar(c); 
end; 
exports 
    translate; 

在C相關部分:

typedef char*(__stdcall *translate)(char*, char*); 
translate MyTranslate; 
... 
MyTranslate = (translate)GetProcAddress(dll, "translate"); 
char* result = (*MyTranslate)(file1, file2); 

相反__stdcall的上面的c我試過__cdecl和__fastcall,但我總是得到ESP消息。另外,在Dephi函數代碼中,該函數似乎返回char *,但是dll文件聲明它返回「true」或「false」(?)。所以在c而不是「typedef char * ...」我試過「typedef BOOL ...」:仍然,我得到ESP消息。我知道我可以在「Basic Runtime Checks」(基本運行時檢查)下抑制該消息(請參閱here),但我寧願讓調用語法正確。該DLL是用UPX壓縮的,但我不確定它是否相關(就像我說的,該函數本身工作)。

+0

如果你不能得到代碼,這將是棘手的!從DLL中返回一個'char *'函數似乎很奇怪。誰來負責釋放這些記憶? – 2011-05-09 08:38:21

+0

我試過更合理的返回值,布爾也是。無論哪種情況,我都會收到ESP警告。 – MrSparkly 2011-05-09 22:29:04

+0

嗯...也許德爾福指針是4字節長,你的C指針是8字節長?你能編譯32位嗎? – pmg 2011-05-09 23:17:36

回答

0

我相信問題在於你的Delphi函數描述不正確。 你所能做的只是用__stdcall標記'翻譯'功能。

當您試圖根據一個描述調用一個COM對象並且它實際上有一個不同的錯誤時,會發生這種錯誤。使用COM對象會發生這種情況,因爲您的計算機上可能有更多的COM對象版本,並且加載了不正確的版本。所以,這是一個類似dll的問題。

但在你的情況下,我相信你完全知道你的Delphi DLL從哪裏加載。所以我認爲這只是該DLL特定版本的不正確文檔。

0

如果dll使用Borland fastcall(EAX, EDX, ECX)並且編譯器使用的是Microsoft fastcall(EAX, EDX),那可能會導致ESP寄存器快速失去同步。