Win VS2008调用约定:来自c的Delphi dll
从 ac 应用程序(VS2008,Win)中,我调用 Borland 中用 Delphi 编写的 dll 中的函数。该函数可以工作,但每次调用后我都会收到此错误:“ESP 的值未在函数调用中正确保存[…]”,这意味着我的调用约定是错误的。我不知道Delphi,我没有完整的dll代码,但我相信这是Delphi函数:
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);
而不是上面c中的__stdcall,我尝试过__cdecl和__fastcall,但我总是得到ESP 消息。另外,在 Dephi 函数代码中,该函数似乎返回 char*,但 dll 文档说它返回“true”或“false”(?)。因此,在 c 中,我尝试了“typedef BOOL...”而不是“typedef char*...”:仍然收到了 ESP 消息。我知道我可以抑制“基本运行时检查”下的消息(请参阅 here),但我宁愿让调用语法正确。该dll是用UPX压缩的,但我不确定它是否相关(就像我说的,该函数本身可以工作)。
From a c app (VS2008, Win), I call a function in a dll written in Delphi in Borland. 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. I don't know Delphi and I don't have the full dll code, but I believe this is the Delphi function:
function translate(file1, file2: PChar):PChar; stdcall;
...
Result:=PChar(c);
end;
exports
translate;
The relevant part in 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. Also, in the Dephi function code the function seems to return char*, but the dll doc says it returns "true" or "false" (?). So in c instead of "typedef char*..." I've tried "typedef BOOL...": still, I get the ESP message. 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).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我相信问题是你的 Delphi 函数描述不正确。
您所能做的就是用 __stdcall 正确标记“翻译”函数。
当您尝试根据一个描述调用 COM 对象而它实际上有不同的描述时,就会发生这种错误。对于 COM 对象,会发生这种情况,因为您的计算机上可能存在多个 COM 对象版本,并且加载了不正确的版本。所以,这是一个类似 dll 地狱的问题。
但就你的情况而言,我相信你非常清楚 Delphi DLL 是从哪里加载的。所以我认为这对于该特定版本的 DLL 来说是不正确的文档。
I believe the problem is that your Delphi function description isn't correct.
All you could do is rightly mark the 'translate' function with __stdcall.
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. 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. So, this is a dll-hell-like problem.
But in your case I believe that you know perfectly well where your Delphi DLL is loaded from. So I think it's just incorrect doc for that particular version of the DLL.
如果 dll 使用 Borland
fastcall(EAX, EDX, ECX)
并且编译器使用 Microsoftfastcall(EAX, EDX)
,则可能会导致 ESP 寄存器失去同步迅速地。If the dll is using Borland
fastcall(EAX, EDX, ECX)
and the compiler is using Microsoftfastcall(EAX, EDX)
, that could cause the ESP register to lose sync quickly.