При помощи Pascal-сценариев можно вызывать функции из внешних библиотек DLL. Сюда относятся как стандартные функции API Win32 из системных библиотек Windows, так и пользовательские функции из пользовательских библиотек DLL. Кроме того, поддерживается вызов .NET сборок.
Пример использования внешних библиотек DLL показан в файле сценария "CodeDll.iss" из папки "Examples" по месту установки Inno Setup.
Папка "Examples" также содержит три примера проекта создания пользовательских DLL: один для Microsoft Visual C++, один для Microsoft Visual C# и один для Borland Delphi. Проект для C# демонстрирует пример создания .NET сборки, совместимой с Pascal-сценарием.
Для вызова функции из библиотеки DLL сначала, как обычно, следует записать прототип функции, но вместо тела функции необходимо использовать ключевое слово 'external' и указать DLL. Если, к примеру, функция имеет прототип function A(B: Integer): Integer;, то для неё поддерживаются следующие три формы:
[Code] function A(B: Integer): Integer; external '<dllfunctionname>@<dllfilename>'; function A(B: Integer): Integer; external '<dllfunctionname>@<dllfilename> <callingconvention>'; function A(B: Integer): Integer; external '<dllfunctionname>@<dllfilename> <callingconvention> <options>';
Первая форма определяет вызов DLL-функции с использованием соглашения о вызовах по умолчанию, т.е. 'stdcall'. Все стандартные функции API Win32 и большинство пользовательских DLL-функций используют 'stdcall'.
Вторая форма определяет вызов DLL-функции с использованием специального соглашения о вызовах. Допустимыми соглашениями о вызовах являются: 'stdcall' (по умолчанию), 'cdecl', 'pascal' и 'register'.
Третья форма определяет один или несколько параметров загрузки DLL, разделённых пробелами:
Определяет отложенную загрузку библиотеки DLL. Как правило, при запуске Pascal-сценарий проверяет доступность вызываемых DLL-функций и в случае отсутствия одной из них прекращает свою работу. Этого не произойдёт, если указать отложенную загрузку 'delayload': библиотека будет загружена не сразу, а только при первом обращении к функции. Используйте отложенную загрузку, когда не знаете, что при выполнении вызываемая DLL-функция будет фактически доступной. В случае невозможности её вызова Pascal-сценарий продолжит свою работу, но вызовет исключение, которое можно перехватить и корректно обработать отсутствие DLL-функции.
Определяет загрузку библиотеки DLL с флагом LOAD_WITH_ALTERED_SEARCH_PATH, который, по сути, заставляет загрузчик выполнять поиск зависимых DLL, начиная с каталога, в котором находится DLL.
Определяет загрузку библиотеки DLL только при выполнении сценария из программы установки.
Определяет загрузку библиотеки DLL только при выполнении сценария из программы удаления.
Например (вторая форма), если в библиотеке DLL функция называется 'A2', файл DLL имеет имя 'MyDll.dll' и DLL-функция использует соглашение о вызовах 'stdcall', то код записывается следующим образом:
[Code] function A(B: Integer): Integer; external 'A2@MyDll.dll stdcall';
Имя файла DLL может содержать константы.
При установке можно использовать специальную приставку 'files:', чтобы инструктировать программу установки автоматически извлекать один или более файлов DLL, указанных в секции [Files], до загрузки первой библиотеки DLL. Например:
[Files] Source: "MyDll.dll"; Flags: dontcopy Source: "A.dll"; Flags: dontcopy Source: "B.dll"; Flags: dontcopy [Code] procedure MyDllFunc(hWnd: Integer; lpText, lpCaption: AnsiString; uType: Cardinal); external 'MyDllFunc@files:MyDll.dll stdcall'; procedure ADllFunc(hWnd: Integer; lpText, lpCaption: AnsiString; uType: Cardinal); external 'ADllFunc@files:A.dll,B.dll stdcall loadwithalteredsearchpath'; //A.dll зависит от B.dll
Когда используется приставка 'files:' и включено непрерывное сжатие, постарайтесь разместить все файлы DLL в начале списка файлов секции [Files]. Чтобы извлечь произвольный файл в инсталляторе с непрерывным сжатием, программа установки должна будет сперва распаковать все предыдущие файлы, используя временный буфер в памяти. Это может привести к существенной задержке в работе инсталлятора, если перед необходимым файлом DLL перечислен ряд других файлов.
Используйте CreateCallback для выполнения вызова из DLL-функций напрямую в функции вашего сценария (подобно функциям API Windows).