I'm using Delphi to make an XLL add-in for Excel, which involves making a lot of calls to the Excel4v function of xlcall32.dll. However, as I'm guessing very few Delphi experts here have worked with that specific API, I'm hoping that the problem might have been observed in other APIs too.
In C, specifically in the xlcall.h file that comes with the Microsoft Excel 2007 XLL SDK, Excel4v is defined as:
int pascal Excel4v(int xlfn, LPXLOPER operRes, int count, LPXLOPER opers[]);
In Delphi I'm using:
function Excel4v(xlfn: Integer; operRes: LPXLOPER; count: Integer;
opers: array of LPXLOPER): Integer; stdcall; external 'xlcall32.dll';
LPXLOPER is a pointer to a struct (in C) or record (in Delphi).
I've been doing my homework on declaring C functions in Delphi (this excellent article was a great help), and I think I'm declaring Excel4v properly. However, calls from Delphi code into that function cause exceptions ("access violation..." is what I keep seeing) unless they are followed by the following line:
asm pop sink; end;
Where "sink" is defined somewhere as an integer.
I have no clue about assembly... So there's no way would I have thought to try fixing the exceptions with "asm pop sink; end;". But "asm pop sink; end;" does indeed fix the exceptions. I first saw it used in this useful article on making XLLs using Delphi. Here's the most relevant quote:
"From Delphi the big stumbling block with add-ins is the extra parameter after the return address on the stack. This comes free with every call to Excel. I’ve never found out what it holds, but so long as you throw it away, your add-in will work fine. Add the line asm pop variable, end; after every call where variable can be any global, local or object variable that is at least 4 bytes long- integer is fine. To repeat- THIS MUST BE INCLUDED after every Excel4v call. Otherwise you are constructing a time-bomb."
Basically I want to understand what's actually happening, and why. What could be causing a Win32 function to return an "extra parameter after the return address on the stack", and what does that actually mean?
Might there be another way to fix this, e.g. with a different compiler option or a different way of declaring the function?
And is there anything risky about calling "asm pop sink; end;" after every call to Excel4v...? It seems to work fine, but, as I don't understand what's going on, it feels a little dangerous...