Delphi 调用库函数会占用堆栈。为什么?

Delphi 调用库函数会占用堆栈。为什么?,delphi,crash,stack,delphi-xe3,Delphi,Crash,Stack,Delphi Xe3,对不起,也许这对Delphi程序员来说也很容易,但对我来说不是。我正在调用一个库函数,它基本上会吃掉我的堆栈。它是通过将函数的变量推入堆栈来实现的,但是Delphi不会以某种方式将它们从堆栈中弹出。因此,在函数结束后,我将在任何地方着陆。有趣的是,只要我有参数,我就可以做“pop-eax”,而且很有效。有人能解释发生了什么事吗? 工作代码如下所示: function LoadIntoMemory(sdiPath: String): Integer; var retValue: Intege

对不起,也许这对Delphi程序员来说也很容易,但对我来说不是。我正在调用一个库函数,它基本上会吃掉我的堆栈。它是通过将函数的变量推入堆栈来实现的,但是Delphi不会以某种方式将它们从堆栈中弹出。因此,在函数结束后,我将在任何地方着陆。有趣的是,只要我有参数,我就可以做“pop-eax”,而且很有效。有人能解释发生了什么事吗? 工作代码如下所示:

function LoadIntoMemory(sdiPath: String): Integer;
var
   retValue: Integer;
begin
  retValue := file_open(PAnsichar(AnsiString(sdiPath)), @filedata, @filedatasize);
   asm
     pop eax
     pop eax
     pop eax
   end;
 end;
function file_open (filename: PAnsichar; filedata: PPAnsichar; filedatasize: PLongInt): Integer; stdcall; external  'libLib';
如前所述,如果没有从堆栈中弹出,它就会崩溃

函数本身来自C DLL,静态链接如下:

function LoadIntoMemory(sdiPath: String): Integer;
var
   retValue: Integer;
begin
  retValue := file_open(PAnsichar(AnsiString(sdiPath)), @filedata, @filedatasize);
   asm
     pop eax
     pop eax
     pop eax
   end;
 end;
function file_open (filename: PAnsichar; filedata: PPAnsichar; filedatasize: PLongInt): Integer; stdcall; external  'libLib';

动态链接不会改变行为。

好的,我现在有了。抱歉,可能是简单的RTFM问题。我应该使用cdecl;而不是stdcall。只希望所有这些Delphi DLL链接教程都能在某个地方提到它


这是呼叫约定不匹配。被调用方是cdecl,调用方使用stdcall。关键区别在于谁清理堆栈。对于stdcall,它是被调用方;对于cdecl,它是调用方

这就解释了你所观察到的情况。实际功能是cdecl。因此,不会清理堆栈。但是调用代码认为函数是stdcall,因此希望被调用方清理堆栈。因此,任何一方都不会清洗它

这里有更多详细信息:

我想试试“cdecl”。我不确定这是否有用,因为变量的顺序会改变。