MB.*_*MB. 6 c delphi assembly winapi xll
我正在使用Delphi为Excel制作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[]);
Run Code Online (Sandbox Code Playgroud)
在Delphi我正在使用:
function Excel4v(xlfn: Integer; operRes: LPXLOPER; count: Integer;
opers: array of LPXLOPER): Integer; stdcall; external 'xlcall32.dll';
Run Code Online (Sandbox Code Playgroud)
LPXLOPER是指向结构(在C中)或记录(在Delphi中)的指针.
我一直在做我在Delphi中声明C函数的功课(这篇优秀的文章是一个很好的帮助),我想我正在宣布Excel4v.但是,从Delphi代码调用该函数会导致异常("访问违规......"是我一直看到的),除非后面跟着以下行:
asm pop sink; end;
Run Code Online (Sandbox Code Playgroud)
其中"sink"在某处定义为整数.
我对组装没有任何线索......所以我没想办法用"asm pop sink; end;"来修复异常.但是"asm pop sink; end;" 确实修复了异常.我第一次看到它在这篇有用的文章中用于使用Delphi制作XLL.这是最相关的报价:
"来自Delphi,带有加载项的大绊脚石是堆栈上返回地址之后的额外参数.每次调用Excel都可以免费使用.我从来没有发现它拥有什么,但只要你扔掉它,你的加载项工作正常.添加行asm pop变量,结束;在每次调用之后,变量可以是任何至少4个字节长的全局,局部或对象变量 - 整数就好了.要重复 - 这必须是在每次Excel4v通话后都包括在内.否则你正在制造定时炸弹."
基本上我想了解实际发生了什么,以及为什么.什么可能导致Win32函数返回"堆栈上的返回地址后的额外参数",这实际上是什么意思?
可能有另一种方法来解决这个问题,例如使用不同的编译器选项或声明函数的不同方式?
并且有什么风险可以称为"asm pop sink; end;" 每次调用Excel4v后......?它看起来工作正常,但是,由于我不明白发生了什么,感觉有点危险......
我不相信它是pascal vs stdcall - 它们是非常相似的调用约定,不应该在函数退出时导致不匹配的堆栈.
从引用的文章中,
这确实是一个非常好的语法,但它与上面的数组定义不同.数组参数是开放数组参数.它们可能看起来像任何数组,并且它们接受任何数组,但它们会获得一个额外的(隐藏)参数,该参数保存数组中的最高索引(高值).因为这只是在Delphi中,而不是在C或C++中,所以你会遇到一个真正的问题.(另请参阅我关于开放数组的文章),因为参数的实际数量不匹配.
您将获得传递给函数的额外"最高数组索引"参数.这是一个int,当函数退出时必须清理它,这样你就不会遇到损坏的堆栈并崩溃.本文指出如何将数组传递给C函数.
就像是:
type
PLPXLOPER = ^LPXLOPER;
Run Code Online (Sandbox Code Playgroud)
并将PLPXLOPER作为最后一个参数传递.
归档时间: |
|
查看次数: |
1651 次 |
最近记录: |