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[]);
Delphiで私が使用しているもの:
function Excel4v(xlfn: Integer; operRes: LPXLOPER; count: Integer;
opers: array of LPXLOPER): Integer; stdcall; external 'xlcall32.dll';
LPXLOPERは、構造体(Cの場合)またはレコード(Delphiの場合)へのポインターです。
私はDelphiでC関数を宣言するための宿題をしてきました(このすばらしい記事は大きな助けになりました)。Excel4vを正しく宣言していると思います。ただし、Delphiコードからその関数を呼び出すと、次の行が続かない限り、例外が発生します(「アクセス違反...」が表示され続けます)。
asm pop sink; end;
ここで、「シンク」はどこかで整数として定義されます。
アセンブリについての手がかりがありません...したがって、「asmpopsink;end;」で例外を修正しようと考える方法はありません。しかし、「asmpopsink;end;」確かに例外を修正します。Delphiを使用したXLLの作成に関するこの便利な記事で最初に使用されたのを見ました。最も関連性の高い引用は次のとおりです。
「Delphiの場合、アドインの大きな障害は、スタックの差出人住所の後の追加パラメータです。これは、Excelを呼び出すたびに無料になります。何が保持されているかはわかりませんが、破棄する限り、アドインは正常に機能します。行asm pop変数を追加し、終了します。変数がグローバル、ローカル、またはオブジェクト変数である可能性があるすべての呼び出しの後に、長さ4バイト以上の整数で問題ありません。繰り返すには、これを行う必要があります。すべてのExcel4v呼び出しの後に含まれます。それ以外の場合は、時限爆弾を作成しています。」
基本的に、実際に何が起こっているのか、そしてその理由を理解したいと思います。Win32関数が「スタック上のリターンアドレスの後に余分なパラメータ」を返す原因は何でしょうか。それは実際にはどういう意味ですか。
これを修正する別の方法がありますか?たとえば、別のコンパイラオプションや、関数を宣言する別の方法を使用しますか?
そして、「asmpopsink;end;」と呼ぶのに危険なことはありますか。Excel4vを呼び出すたびに...?うまくいくようですが、何が起こっているのかわからないので少し危険な感じがします...