PVOzerski » 13.07.2005 11:37:51
Давайте немного разберемся...
И с терминологией, и с сутью.
О языках программирования. В данном случае нас интересуют два - Си и Паскаль. СтОит вспомнить еще Си++ как самый распространенный у разработчиков, но применительно к "скрещиванию" с FPC он пока не обычно очень актуален из-за несовместимости классов. Поэтому не буду его трогать.
О файлах, используемых в сборке приложений:
1) тексты программ - для Си они обычно имеют расширения .c, для FPC - .pp или .pas.
2) заголовочные файлы (хедеры) для Си - .h. У современного Паскаля несколько иная концепция, хедеров в строгом смысле у него нет, по смыслу к ним приближаются интерфейсные разделы модулей (расширения всё теже .pas и .pp). Однако в Паскале иногда используются и include-файлы (обычно с расширением .inc). В случае FPC они могут содержать почти любые куски текста на Паскале. В другие части проекта они включаются директивой {$i ...} или {$include ...}
3) Obj-файлы - двоичные результаты компиляции, предназначенные для сборки линкером и не делимые далее штатными средствами. В юниксах обычно имеют расширение .o.
4) Статические библиотеки - архивы obj-файлов, из которых линкер может вытаскивать нужные obj-модули в процессе сборки приложения и вставлять их код в собираемое приложение. В юниксах обычно имеют расширение .a.
5) Динамические (разделяемые) библиотеки - наборы функций в двоичном виде, код которых может вызываться приложениями без включения в единый с ним файл. В юниксах обычно имеют расширение .so.
6) Интерфейсные двоичные вспомогательные модули FPC, используемые компилятором для эффективного получения информации о содержимом obj-файла или статической библиотеки. В FPC версий старше 1.0.10 имеют расширение .ppu, в более старых версиях - в зависимости от платформы разные. При компиляции модуля (unit) компилятор FPC создает 2-3 файла - .ppu, .o и (опционально) .a.
Если мы имеем дело с obj-файлом, созданным компилятором Си, к нему изначально не прилагается .ppu - файла, поэтому указать его в uses-разделе невозможно. Содержащиеся в нем функции объявляются как external. А параметры и соглашения об их передачи контролируются самим программистом.
Например,
procedure proc1(p1: integer; p2: pchar); cdecl; external;
Этот подход поддерживается и компиляторами от Borland, но у FPC синтаксис несколько усовершенствован. Так, можно разрешить проблему недопустимых с точки зрения Паскаля имен, добавив директиву name:
procedure proc2(p1: integer; p2: pchar); stdcall; external name 'proc2@8';
А чтобы не линковать потом всё вручную, в FPC (как и в компиляторах от Borland) есть директива {$L ...}
Естественно, не возбраняется объединить эти функции в отдельный юнит. Что отчасти и сделано разработчиками.
Со статическими библитеками у FPC дело обстоит похоже , только нужно использовать директиву {$Linklib ..., static}. Единственная тонкость, притом, похоже, это по-разному у разных версий - проблема расширений и префиксов. Так, в юниксах обычно отбрасывают начальное "lib", а расширение .a тоже может подразумеваться. Например, для прилинковки библиотеки libfoo.a директива комплятора будет такая: {$linklib foo, static}
При использовании динамических библиотек в случае юниксов и win подходит почти такой же синтаксис, только без слова static. Кроме того, водможен и "дельфийский" стиль. При этом, в отличие от Delphi, FPC сам может подставить правильное расширение динамической библиотеке, что удобно для переноса с платформы на платформу.
В документации к FPC описано также подключение external-переменных из obj-файлов или статических библиотек - принцип тот же.