Статическое связывание
Теперь создадим клиента. Организуйте новый проект, сохраните его в другом каталоге. В используемых модулях допишите еще один – StdCtrls;
В секции implementation введите строку:
procedure DrawBMP (Handle:THandle); stdcall; external 'Project1.dll';
Этим мы декларируем нужную нам функцию. Ключевое слово external указывает, что данная функция размещена в библиотеке с указанным далее именем. Ключевое слово stdcall является директивой и, определяет вызов функции стандартным для операционной системы образом – параметры помещаются в стек слева направо, очистка стека осуществляется вызываемой процедурой. Этот вызов обеспечивает обработку фиксированного числа параметров. При использовании импортируемых функций такие параметры задаются обязательно.
Помимо директивы stdcall существуют и другие директивы вызова:
Register – эта директива используется по умолчанию. Вызов такого типа называется быстрым (fast call). В нем используются три расширенных регистра процессора, в которые помещаются переменные длинной не более 32-х разрядов и указатели. Остальные параметры помещаются в стек слева направо. После использования стек очищается вызываемой процедурой.
Pascal – реализует вызовы в стиле языка Pascal. За очистку стека отвечает вызываемая процедура. Параметры помещаются в стек слева направо. Этот способ вызова является очень быстрым, но не поддерживает переменное число параметров. Используется для поддержки обратной совместимости.
Sdecl – реализует вызовы в стиле языка С. Параметры в стек помещаются справа налево. Очистка стека осуществляется вызывающей процедурой. Такие вызовы обеспечивают обслуживание переменного числа параметров, но скорость обработки меньше, чем в вызовах pascal.
Safecall – параметры помещаются в стек справа налево. Очистка стека осуществляется вызываемой процедурой. Используется в COM и основанных на ней технологиях.
На форме разместите кнопку, в процедуре обработки события щелчка кнопки мыши которой введите строку: DrawBMP(Canvas1.Handle);
Теперь откомпилируйте проект. Если просмотреть откомпилированный проект с помощью утилиты быстрого просмотра (она обязательно должна быть установлена на вашем компьютере), то можно увидеть, что помимо нашей функции DrawBMP, в нем содержится большое количество других функций, отвечающих за появление окна приложения, вывод на канве окна, отвечающих за реакцию приложения на события. Эти функции называются системными. Так же называются и библиотеки, хранящие код таких его функций.
Delphi позволяет нам писать краткий и удобочитаемый код, но при компиляции этот код преобразуется к вызову массы системных функций (функций API). При этом мы жертвуем размерами и скоростью работы приложений, созданных в Delphi. Если же скорость работы приложения чрезвычайно важна, то можно написать приложение исключительно на функциях API.
Вернемся к нашему примеру. Если Вы сейчас попробуете запустить его, то сразу после запуска появится системное окно с сообщением о том, что необходимый файл библиотеки не найден. Для того, чтобы данная библиотека была доступна любому приложению, необходимо поместить ее в один из каталогов общего доступа, например Windows.
Главное в рассмотренном примере то, что код приложения не содержит напрямую ничего, связанного с отображаемой в окне картинкой. Приложение обращается к указанной нами библиотеке динамической компоновки, которая выполняет всю работу по выводу изображения.
В коде клиента указывается имя вызываемой функции, но во время работы откомпилированного приложения клиент при вызове динамической библиотеки ориентируется по соответствующей функции точке входа, адрес которой он получает при инициализации библиотеки.