从Delphi调用特定的Win32 API – 为什么异常会在没有“asm pop
我正在使用Delphi为Ex??cel制作XLL加载项,这涉及对xlcall32.dll的
Excel4v函数进行大量调用.但是,我猜这里的Delphi专家很少使用这个特定的API,我希望在其他API中也可以观察到这个问题.
在C中,特别是在Microsoft Excel 2007 XLL SDK附带的xlcall.h文件中,Excel4v定义为: int pascal Excel4v(int xlfn,LPXLOPER operRes,int count,LPXLOPER opers[]); 在Delphi我正在使用: function Excel4v(xlfn: Integer; operRes: LPXLOPER; count: Integer; opers: array of LPXLOPER): Integer; stdcall; external 'xlcall32.dll'; LPXLOPER是指向结构(在C中)或记录(在Delphi中)的指针. 我一直在做我在Delphi中声明C函数的功课(this excellent article是一个很好的帮助),我想我正在宣布Excel4v.但是,从Delphi代码调用该函数会导致异常(“访问违规……”是我一直看到的),除非后面跟着以下行: asm pop sink; end; 其中“sink”在某处定义为整数. 我对组装没有任何线索……所以我没想办法用“asm pop sink; end;”来修复异常.但是“asm pop sink; end;”确实修复了异常.我第一次看到它在this useful article on making XLLs using Delphi中使用.这是最相关的引用:
基本上我想了解实际发生了什么,以及为什么.什么可能导致Win32函数返回“堆栈上的返回地址后的额外参数”,这实际上是什么意思? 可能有另一种解决方法,例如使用不同的编译器选项或声明函数的不同方式? 并且有什么风险可以称为“asm pop sink; end;”每次调用Excel4v后……?它看起来工作正常,但是,由于我不明白发生了什么,感觉有点危险…… 解决方法
我不相信它是pascal vs stdcall – 它们是非常相似的调用约定,不应该在函数退出时导致不匹配的堆栈.
从引用的article,
您将获得传递给函数的额外“最高数组索引”参数.这是一个int,当函数退出时必须清理它,这样你就不会遇到损坏的堆栈并崩溃.本文指出如何将数组传递给C函数. 就像是: type PLPXLOPER = ^LPXLOPER; 并将PLPXLOPER作为最后一个参数传递. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |