Я использую Delphi для создания надстройки XLL для Excel, которая включает в себя множество обращений к Excel4v функции xlcall32.dll. Однако, как я предполагаю, очень немногие эксперты Delphi здесь работали с этим конкретным API, я надеюсь, что проблема могла наблюдаться и в других API.
В C, особенно в файле xlcall.h, который поставляется с Microsoft Excel 2007 XLL SDK 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).
Я делал домашнюю работу по объявлению функций C в Delphi (эта отличная статья была отличная помощь), и я думаю, что правильно объявляю Excel4v. Однако вызовы из кода Delphi в эту функцию вызывают исключения («нарушение прав доступа ...» - это то, что я продолжаю видеть) , если за ними не следует следующая строка:
asm pop sink; end;
Где «сток» определяется где-то как целое число.
Я понятия не имею о сборке ... Так что я бы ни за что не подумал попробовать исправить исключения с помощью "asm pop раковина; end;". Но "asm pop раковина; конец;" действительно исправляет исключения. Впервые я увидел его в этой полезной статье о создании файлов XLL используя Delphi. Вот самая актуальная цитата:
«В Delphi большой камень преткновения с надстройками - это дополнительный параметр после адреса возврата в стеке. Он предоставляется бесплатно при каждом вызове Excel. Я так и не узнал, что он содержит, но если вы его выбросите , ваша надстройка будет работать нормально. Добавьте строку asm pop variable, end; после каждого вызова, где переменная может быть любой глобальной, локальной или объектной переменной длиной не менее 4 байтов, можно использовать длинное целое число. Чтобы повторить - ЭТО ДОЛЖНО БЫТЬ ВКЛЮЧАЕТСЯ после каждого вызова Excel4v. В противном случае вы создаете бомбу замедленного действия ».
В основном я хочу понять, что на самом деле происходит и почему. Что могло заставить функцию Win32 возвращать «дополнительный параметр после адреса возврата в стеке» и что это на самом деле означает?
Может быть другой способ исправить это, например с другим параметром компилятора или другим способом объявления функции?
И есть ли что-нибудь рискованное в том, чтобы называть "asm pop раковина; конец;" после каждого вызова Excel4v ...? Вроде работает нормально, но, поскольку я не понимаю, что происходит, кажется немного опасным ...