简体   繁体   English

赢得VS2008调用约定:来自C的Delphi dll

[英]Win VS2008 calling convention: Delphi dll from c

From ac app (VS2008, Win), I call a function in a dll written in Delphi in Borland. 从交流应用程序(VS2008,Win),我用Borland的Delphi编写的dll中调用一个函数。 The function works, but after each call I get this error: “The value of ESP was not properly saved across a function call[…]” which means my calling convention is wrong. 该函数有效,但是在每次调用后,我都会收到以下错误消息:“ ESP的值未在函数调用中正确保存[…]”,这意味着我的调用约定错误。 I don't know Delphi and I don't have the full dll code, but I believe this is the Delphi function: 我不知道Delphi,也没有完整的dll代码,但是我相信这是Delphi函数:

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

The relevant part in c: c中的相关部分:

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

Instead of __stdcall in c above I've tried __cdecl and __fastcall, but I always get the ESP message. 我没有尝试上面c中的__stdcall,而是尝试了__cdecl和__fastcall,但是我总是收到ESP消息。 Also, in the Dephi function code the function seems to return char*, but the dll doc says it returns "true" or "false" (?). 同样,在Dephi函数代码中,该函数似乎返回char *,但是dll文档说它返回“ true”或“ false”(?)。 So in c instead of "typedef char*..." I've tried "typedef BOOL...": still, I get the ESP message. 因此,在c中而不是“ typedef char * ...”,我尝试了“ typedef BOOL ...”:仍然,我得到了ESP消息。 I know I can suppress the message under "Basic Runtime Checks" (see here ), but I'd rather get the calling syntax right. 我知道我可以在“基本运行时检查”下隐藏该消息(请参阅此处 ),但是我宁愿正确使用调用语法。 The dll is compressed with UPX, but I'm not sure if it's relevant (like I said, the function itself works). dll是用UPX压缩的,但是我不确定它是否相关(就像我说的那样,该函数本身可以工作)。

I believe the problem is that your Delphi function description isn't correct. 我相信问题是您的Delphi函数描述不正确。 All you could do is rightly mark the 'translate' function with __stdcall. 您所能做的就是用__stdcall正确标记“ translate”功能。

This kind of error occures when you try to invoke a COM object according to a one description and it actually has a different one. 当您尝试根据一个描述调用一个COM对象时,会发生这种错误,而实际上却是另一种错误。 With COM objects it happends because there can be more that one version of the COM object on your machine and incorrect version is loaded. 有了COM对象,就会发生这种情况,因为您的计算机上可能存在一个以上版本的COM对象,并且加载了错误的版本。 So, this is a dll-hell-like problem. 因此,这是一个类似于dll地狱的问题。

But in your case I believe that you know perfectly well where your Delphi DLL is loaded from. 但是对于您的情况,我相信您完全知道从何处加载Delphi DLL。 So I think it's just incorrect doc for that particular version of the DLL. 因此,我认为该特定版本的DLL只是不正确的文档。

如果dll使用Borland fastcall(EAX, EDX, ECX) ,而编译器使用Microsoft fastcall(EAX, EDX) ,则可能导致ESP寄存器快速失去同步。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM