Harbour для начинающих

Как установить Harbour и откомпилировать на нем свою программу. Особенности Harbour.

Александр Кресин
2003 - 2016

Скачать одним файлом: chm, версия 1.02

При написании этой статьи были использованы материалы из Harbour/readme.txt, Harbour/Changelog, Harbour/doc/xhb-diff.txt и др. файлов из Harbour/doc/, из Harbour developers list, исходные файлы проекта.




1. Установка

1.1 Скачиваем Harbour

Самый очевидный и простой способ заполучить Harbour - это зайти на сайт проекта - https://harbour.github.io/. Кнопка More downloads приведет вас на страницу проекта на Sourceforge, где выложены как исходники, так и готовые к работе бинарные пакеты разных версий. Если вам нужен бинарник, то выбираете предназначенный для вашей платформы ( Windows, какой-либо из Юниксов/Линуксов, OS/2 и пр. ). Может оказаться, что такого нет, или что для вашей платформы отсутствует последняя версия - это часто бывает, т.к. разных Юниксов/Линуксов много, а число активных разработчиков - тех кто готов компилировать, тестировать и выкладывать пакеты на разных платформах - ограничено. Так вот, если не найдете свой пакет, не расстраивайтесь - путь к Харбору для вас не закрыт. Скачивайте исходники и собирайте из них готовый к работе бинарный пакет. Это совсем не сложно, гораздо проще, чем может показаться сначала. Кстати, если для нужной вам платформы отсутствует бинарный пакет последней версии, может быть, имеет смысл скачать ту версию, которая есть. И 2.0, и даже 1.0 вполне хороши и, возможно, будут полностью удовлетворять вашим потребностям.

С сайта проекта вы можете скачать архив свежих исходников ( он там называется Source snapshot ) и так называемые nightly binary это готовый к использованию дистрибутив, откомпилированный из репозитария разработчиков прошедшей ночью.

При желании можно достать исходники непосредственно из репозитария разработчиков с помощью GIT-клиента ( с марта 2013 Harbour перебрался с SVN на GIT на https://github.com/harbour/. Лично я не вижу в этом большого смысла, разве только вы решите присоединиться к разработчикам или для вас критически важен код, выложенный пять минут назад... Если так, то почитайте следующий подраздел - про GIT.

1.2 Что такое GIT

Git ( см. статью в Википедии ) - это современная система управления версиями, преемник CVS и конкурент SVN. Итак, Git - это программа с серверной и клиентской частями, которая позволяет разработчикам, у которых установлены клиентские части, совместно работать с исходниками проекта, которые находятся на сервере ( в Интернет или в локальной сети ), разрешает конфликты, возникающие при одновременном изменении одного файла разными людьми. При этом Git обеспечивает и контроль версий - т.е., все версии каждого файла хранятся, могут быть извлечены, восстановлены; можно проверить, кем и какие изменения были сделаны.
Очень удобная штука, рекомендую ее, или ее предшественника CVS, и для внутреннего использования в организации.

Харбор "живет" с марта 2013 года на Github.com - одном из крупнейших порталов для Open Source проектов. Установив Git клиент, вы можете получить доступ к исходникам Харбора - самому последнему варианту, как у разработчиков. В первый раз вам придется скачать полный набор, при последующих обращениях передаваться будут только изменения.

Git клиент можно скачать с сайта этого продукта. Если у вас Линукс, то, возможно, клиент SVN входит в состав вашего дистрибутива. Если у вас Windows, вы Создаете у себя каталог, например, GIT, и в этом каталоге выполняете команду, которая создаст там каталог core/, а в нем - локальный репозитарий Harbour:

       git.exe clone http://github.com/harbour/core.git
    

А потом время от времени обновляете свой локальный репозитарий, выполняя в core/ команду git pull:

       cd core
       git.exe pull
    

Кроме консольной команды git.exe дистрибутив Git содержит и графическую утилиту, которая, помимо прочего, предоставляет удобные средства для просмотра истории изменений, сравнения версий и т.п.

1.3 Выбираем C компилятор

Есть один важный вопрос, который вам надо решить для себя сразу, до скачивания дистрибутива Харбора - это вопрос о C компиляторе.
Дело в том, что сам компилятор Харбор не создает объектные файлы ( obj, o ), результатом его работы является *.c файл, который надо затем скомпилировать C компилятором, чтобы получить исполняемый файл (exe'шник - для Windows). Но пусть это вас не пугает ! Вам не обязательно знать для этого C - достаточно, чтобы C компилятор был у вас установлен. А использование его для компиляции и линковки ваших файлов ничуть не сложнее, чем использование Rtlink или Blinker'а.
Если вы работаете в Линуксе, или в любом из Unix'ов, в MAC OS, OS/2, то C компилятор у вас уже есть - это стандартный GNU C. если же ваша платформа - Windows, то надо выбирать. Многие из тех, кто работает с Харбором, используют бесплатный Borland C 5.5.1, его можно скачать с этой странички. Другой популярный C компилятор - Mingw http://www.mingw.org. Если у вас уже стоит C++ Builder или Visual C, можете использовать их. Бинарный дистрибутив Harbour под Windows, предоставляемый в виде установочного exe файла, включает в себя Mingw C компилятор.

Примечание для тех, кто будет устанавливать Borland C 5.5.1 и не прочитает их readme.txt: чтобы он работал, необходимо вручную создать в bcc55\bin 2 файла:
BCC32.CFG:

     -I"c:\Borland\Bcc55\include"
-L"c:\Borland\Bcc55\lib"
и ILINK32.CFG:
     -L"c:\Borland\Bcc55\lib;c:\Borland\Bcc55\lib\PSDK"
    

Кстати, чтобы запустить на исполнение небольшую программу, вы можете обойтись и без C.

1.4 Устанавливаем бинарники Harbour

Бинарные пакеты распростаняются в форматах, специфичных для соответствующей платформы. Для Windows это exe'шник - запускаете его и следуете инструкциям установщика; для Ubuntu это deb файл - пользователи Ubuntu знают, что с ним делать; ну и т.д.

1.5 Устанавливаем Harbour из исходников

Чтобы построить Харбор - компилятор и библиотеки, нам необходимо иметь C компилятор, об этом мы уже говорили ранее.

В корне вашего дистрибутива Harbour есть файл README.txt ( до 14.11.2012 он назывался INSTALL ), там содержатся подробные инструкции по сборке Харбора из исходников. Правда, этот файл - на английском языке. Ниже я расскажу об этом очень кратко, для большинства случаев этого будет достаточно.

Если у вас Windows, укажите путь к каталогу bin вашего C компилятора и запускайте win-make.exe - этот файл есть в вашем дистрибутиве Harbour. Я обычно делаю bat'ник с этими строками и запускаю его на исполнение.

Так, если у вас Borland C 5.5, то это будет выглядеть примерно так:

          set path=c:\borland\bcc55\bin
          win-make.exe
    

Для mingw может быть вот так:

          set path=c:\mingw\bin
          win-make.exe
    

Для Open Watcom:

          set watcom=C:\watcom
          set path=%WATCOM%\BINNT;%WATCOM%\BINW;%PATH%
          set edpath=%WATCOM%\EDDAT
          set include=%WATCOM%\H;%WATCOM%\H\NT
          win-make.exe
    

Если у вас Линукс/Юникс, то достаточно запустить команду make.

Примеры для других платформ и компиляторов смотрите в README.txt ( до 14.11.2012 он назывался INSTALL ), раздел 8.EXAMPLES, там их множество.

Для начала этого хватит, но впоследствии вам, возможно, потребуется установить дополнительные переменные окружения для управления процессом сборки. Полный их список смотрите, опять-таки, в README.txt, а здесь я приведу лишь несколько примеров, чтобы было ясно, о чем идет речь.

Некоторые модули Харбора ( в основном, это дополнительные - те, что в contribs ) зависят от так-называемых 3rd party компонентов, т.е. от установленных у вас в системе сторонних программ. Например, для сборки библиотеки hbmysql из Harbour/contrib требуются файлы заголовков ( .h ) от MySql клиента, который у вас установлен. Поэтому, если вы хотите, чтобы эта библиотека была создана при сборке Харбора и чтобы она работала с установленным у вас MySQL клиентом, вы должны указать путь заголовкам этого клиента:

       set HB_WITH_MYSQL=C:\mysql\include
    
Аналогично этому:
       set HB_WITH_ADS=C:\ads\acesdk
       set HB_WITH_ALLEGRO=C:\allegro\include
       set HB_WITH_BLAT=C:\blat\full\source
       set HB_WITH_CAIRO=C:\cairo\include\cairo
       set HB_WITH_CURL=C:\curl\include
       set HB_WITH_GS=C:\ghostscript-9.01\psi
       set HB_WITH_GS_BIN=C:\ghostscript-9.01\bin (on Windows)
       set HB_WITH_FIREBIRD=C:\Firebird\include
       set HB_WITH_FREEIMAGE=C:\FreeImage\Dist
       set HB_WITH_GD=C:\gd\include
       set HB_WITH_OCILIB=C:\ocilib\include
       set HB_WITH_OPENSSL=C:\openssl\inc32 OR C:\openssl\include
       set HB_WITH_PGSQL=C:\pgsql\include
    

На Unix/Linux системах это обычно не требуется, так как все эти 3rd party компоненты расположены в строго определенных местах и программа сборки сама их найдет. Чтобы, наоборот, запретить сборку этих модулей, вам надо присвоить соответствующей переменной значение no

Для некоторых из таких модулей все нужные файлы, и заголовочные в том числе, уже есть в составе Харбора. В этом случае вы можете или, как и выше, указать путь к установленному у вас компоненту, или присвоить переменной значение local - чтобы были использованы те самые Харборовские файлы и заголовки, или, наоборот, nolocal - чтобы запретить использование предопределенных в Харборе файлов:

       set HB_WITH_BZIP2=C:\bzip2
       set HB_WITH_EXPAT=C:\expat\lib
       set HB_WITH_JPEG=C:\jpeglib
       set HB_WITH_LIBHARU=C:\libharu\include
       set HB_WITH_LZF=C:\liblzf
       set HB_WITH_MINILZO=C:\minilzo\
       set HB_WITH_MINIZIP=C:\zlib\contrib\minizip
       set HB_WITH_MXML=C:\minixml
       set HB_WITH_PCRE=C:\pcre
       set HB_WITH_PNG=C:\libpng
       set HB_WITH_SQLITE3=C:\sqlite3
       set HB_WITH_TIFF=C:\libtiff
       set HB_WITH_TINYMT=C:\tinymt\tinymt
       set HB_WITH_XDIFF=C:\libxdiff-0.23\xdiff
       set HB_WITH_ZLIB=C:\zlib
    

Ну и, напоследок, еще одна переменная, она указывает на каталог, куда надо установить бинарники Harbour:

       set HB_INSTALL_PREFIX
    

1.6 xHarbour

xHarbour - это другой Harbour, ответвление (fork) от Harbour. В начале 2000-х один из разработчиков (Рон Пинкас) из-за разногласий с остальными членами команды покинул проект и основал свой. Впоследствии к нему присоединилась еще группа людей. Буква x в названии нового проекта должна была означать extended - расширенный. Код был целиком унаследован от Harbour, но Пинкас внес в него свои изменения/дополнения, многие из которых были ранее отвергнуты основными разработчиками Harbour. По ходу дальнейшей разработки xHarbour заимствовал многое из Harbour и Harbour заимствовал кое-что из xHarbour, так что оба проекта тесно связаны и в большинстве случаев, если не использовать некоторые языковые расширения, программы успешно компилируются и тем, и другим. xHarbour существует в двух ипостасях :) - открытой и коммерческой. Чем они различаются - не знаю, разбирайтесь сами, если хотите. Подробно про различия между Harbour и xHarbour можно почитать в xhb-diff.txt, этот файл есть в любом дистрибутиве Harbour в каталоге Doc. Я с самого начала и до сих пор являюсь членом команды Harbour, использую исключительно его, что рекомендую и вам. Тем более, что на сегодняшний день ( ноябрь 2012 ) Harbour надежнее, быстрее и богаче возможностями. Все, о чем здесь говорится, относится к Harbour. Многое (но не все, Hbmk, например в xHarbour не включена) из этого применимо и для xHarbour.

2. Компиляция и линковка программы

2.1 Общие рассуждения

Собрать свою программу в Harbour можно тремя способами: с помощью традиционной make-системы, которая входит в состав любого C компилятора, с помощью командных файлов ( bat'ников - под Windows и shell скриптов под Unix/Linux ) или используя специальную Harbour утилиту hbmk2. Здесь мы рассмотрим два последних способа.

Hbmk2, безусловно, удобная и мощная утилита. Главное ее достоинство в том, что она позволяет строить как простенькие программы, так и большие проекты, не вдаваясь в детали работы компилятора и линкера. Hbmk2 сама находит ваш C компилятор и производит необходимые действия. Что может быть проще, чем запустить из командной строки утилиту со списком исходных файлов проекта ? Для более сложных случаев - если вам надо обязательно установить какие-то особые опции компиляции, присоединить дополнительные библиотеки, или использовать динамические библиотеки, потребуется знать специальные параметры hbmk2, или даже создавать конфигурационные файлы проекта, но все равно это будет проще, чем использовать другие способы сборки.

Я, тем не менее, предпочитаю традиционный способ сборки - с помощью командных файлов, так как он дает полный контроль над процессом, с ним я четко вижу, что именно я делаю и зачем. Общая последовательность действий здесь простая:

1. Компилируем *.prg в *.c с помощью harbour.exe.
Параметры компилятора, в основном, те же, что и у Клиппера. Полный их список можно получить, запустив harbour.exe без параметров. В одной строчке можно указывать несколько prg файлов.
2. Компилируем *.с в объектные файлы вашим C компилятором.
3. Линкуем объектные файлы тем линкером, который поставляется с C компилятором.
При линковке надо обязательно указать список Харборовских библиотек, которые нужны вашему приложению.
Все используемые с Харбором C компиляторы позволяют объединить шаги 2 и 3 - делайте, как вам нравится.

2.2 Windows, bat файл

Ниже приведен bat'ник, которым я обычно пользуюсь, чтобы скомпилировать один prg (Borland C, gtwin):

      @set HB_INSTALL=d:\harbour

       %HB_INSTALL%\bin\harbour %1.prg -n -i%HB_INSTALL%\include
       bcc32 -O2 -d -I%HB_INSTALL%\include -L%HB_INSTALL%\lib %1.c hbdebug.lib
        hbvm.lib hbrtl.lib gtwin.lib hbcpage.lib hblang.lib hbrdd.lib hbmacro.lib
        hbpp.lib rddntx.lib rddcdx.lib rddfpt.lib hbsix.lib hbcommon.lib hbct.lib 
    

Если вы хотите использовать gtwvt экранный драйвер, то последняя строчка будет выглядеть так:

       bcc32 -O2 -tW -I%HB_INSTALL%\include -L%HB_INSTALL%\lib %1.c hbdebug.lib
        hbvm.lib hbrtl.lib gtwvt.lib hbcpage.lib hblang.lib hbrdd.lib hbmacro.lib
        hbpp.lib rddntx.lib rddcdx.lib rddfpt.lib hbsix.lib hbcommon.lib hbct.lib 
    

Обратите внимание на опцию -i Харбора. Она указывает путь к заголовочным файлам ( *.h и *.ch ), в данном случае - к стандартным заголовочным файлам Харбора, которые обычно находятся в harbour\include. Если в вашей программе нет заголовочных файлов, эту опцию можно опустить. Если же вы используете заголовочные файлы, расположенные где-то в другом месте (свои, или от какой-либо дополнительной библиотеки), вам надо добавить путь к ним в этой опции -i, разные пути могут разделяться точкой с запятой, например:

       %HB_INSTALL%\bin\harbour %1.prg -n -i%HB_INSTALL%\include;c:\hwgui\install
    

Это же относится и к опции -L C компилятора. Она указывает путь к библиотекам, которые должны быть прилинкованы к вашему приложению. Это, конечно же, стандартные библиотеки Харбора, которые обычно находятся в папке harbour\lib, но могут быть и в папке для конкретного C компилятора, например, harbour\lib\win\bcc. Если вы используете дополнительные библиотеки, находящиеся где-то еще, надо добавить путь к ним в опции -L - как это было показано выше для -i.

Для Mingw C компилятора замените команду вызова C компилятора на:

       gcc -Wall -mno-cygwin -c -I%HB_INSTALL%\include %1.c
       gcc -Wall -mwindows -o%1%.exe %1.o -L%HB_INSTALL%/lib/win/mingw -Wl,--start-group \
          -lhbvm -lhbrtl -lgtwvt -lhblang -lhbrdd -lhbmacro -lhbpp -lrddntx -lrddcdx \
          -lrddfpt -lhbsix -lhbcommon -lhbcpage -lhbct -luser32 -lgdi32 -lwinspool \
          -lcomctl32 -luuid -lkernel32 -lws2_32 -Wl,--end-group
    

Если вам надо построить программу из нескольких файлов, то можно использовать что-либо вроде этого (Borland C, gtwin):

      @set HB_INSTALL=d:\harbour

       %HB_INSTALL%\harbour file1.prg -n -i%HB_INSTALL%\include
       %HB_INSTALL%\harbour file2.prg -n -i%HB_INSTALL%\include
       ...
       bcc32 -O2 -d -I%HB_INSTALL%\include -L%HB_INSTALL%\lib file1.c file2.c ...
        hbdebug.lib hbvm.lib hbrtl.lib gtwin.lib hbcpage.lib hblang.lib hbrdd.lib
        hbmacro.lib hbpp.lib rddntx.lib rddcdx.lib rddfpt.lib hbsix.lib hbcommon.lib
        hbct.lib 
    

2.3 Linux, sh скрипт

Последовательность, естественно, та же, только синтаксис немножко другой (для консольного приложения с gtcrs):

       #!/bin/sh
       HB_INS="/apps/harbour"
       $HB_INS/bin/harbour $1.prg -n -q0 -es2 -gc0 -I$HB_INS/include -I../include -d__LINUX__
       gcc -I. -I$HB_INS/include -Wall -c $1.c -o$1.o
       gcc -Wall -o$1 $1.o -L $HB_INS/lib \
       	  -Wl,--start-group -lhbvm  -lhbrtl  -lhblang  -lhbrdd  \
       	  -lhbmacro -lhbpp -lhbcommon -lrddntx -lrddcdx -lrddfpt -lhbsix \
              -lhbct -lgttrm -lhbcpage -Wl,--end-group -lm -lgpm
    

2.4 Hbmk2

С помощью Hbmk2 все немного проще. Чтобы откомпилировать программу из одного prg - файла (например, hello.prg), просто наберите:

       hbmk2 hello.prg
    

Из двух prg:

       hbmk2 mymain.prg second.prg
    

Построить приложение, используя специальный конфигурационный файл проекта:

       hbmk2 myapp.hbp
    

Построить приложение, используя свою библиотеку:

       hbmk2 myapp.prg -lmylib -L
    

Построить приложение, из всех prg и c файлов, расположенных в каталоге src:

       hbmk2 -omyapp src/*.prg src/*.c
    

Hbmk2 сама определяет, какой C компилятор у вас установлен, она ищет путь к нему в переменной окружения PATH. Если у вас больше, чем один установленный C компилятор и хотите указать, какой именно должна использовать hbmk2, пропишите параметр -comp=<name>, где <name> - условное обозначения компилятора, например:

    - для Windows: mingw, msvc, bcc, watcom, icc, pocc, xcc, mingw64, msvc64, msvcia64, iccia64, pocc64;
    - для Linux: gcc, clang, icc, watcom, sunpro, open64, pcc.

Очень полезная опция -trace выводит на экран все вызовы компиляторов и линкера со всеми их опциями, которые потребовались для сборки данного проекта - так вам проще разобраться в проблнмах, если что-то пошло не так, ну и воббще, на мой взгляд, полезно знать, как именно строилось ваше приложение.

2.5 Как использовать динамические библиотеки ( dll, so )

В результате процесса сборки, описанного в предыдущих подразделах, вы получаете исполняемый модуль, который включает в себя ваши исходный тексты, скомпилированные в p-code, виртуальную машину Harbour, которая исполняет этот p-code, RTL - Run-Time Library - библиотеку функций Harbour и, возможно, другие библиотеки, которые вы включили в проект. Поэтому этот исполняемый модуль имеет довольно-таки большой размер. Его можно существенно уменьшить, если использовать динамическую библиотеку. Бинарные дистрибутивы Harbour включают, помимо статических библиотек ( .lib, .a ) и динамическую ( .dll, .so ), которая включает в себя все функции основных библиотек Harbour. Ее название может включать в себя номер версии Harbour и название C компилятора; так, например, для Harbour 2.1, построенного с Borland C, это harbour-21-bcc.dll. Естественно, использоваться такой исполняемый модуль может только совместно с соответствующей динамической библиотекой.

Итак, наш bat'ник для компиляции одного prg c Borland C приобретает такой вид:

      @set HB_INSTALL=d:\harbour

       %HB_INSTALL%\harbour %1.prg -n -i%HB_INSTALL%\include
       bcc32 -O2 -d -I%HB_INSTALL% -L%HB_INSTALL%\lib %1.c hbmainstd.lib harbour-21-bcc.lib
    
Отличие состоит в том, что вместо длинного списка библиотек мы используем теперь только две - hbmainstd.lib и harbour-21-bcc.lib. Последняя представляет собой так называемую import library - библиотеку - указатель на функции из соответствующей dll. Такую библиотеку требуют для статической линковки с dll некоторые C компиляторы, в т.ч. Borland C и MSVC. Mingw и GNU C, кстати, этого не требуют. Название этой библиотеки может быть другим, если у вас другая версия Harbour - harbour-32-bcc.lib, например. Не буду здесь пояснять, для чего нужна hbmainstd.lib - все таки это Harbour для начинающих :), скажу только, что для некоторых GT, gtwvt, например, вместо нее нужно использовать hbmainwin.lib.

Для Mingw C компилятора замените последнюю строчку на:

       gcc -Wall -mno-cygwin -c -I%HB_INSTALL%\include %1.c
       gcc -Wall -mwindows -o%1%.exe %1.o %HB_INSTALL%/lib/win/mingw/harbour-21.dll \
          -L%HB_INSTALL%/lib/win/mingw -Wl,--start-group -lhbmainstd -luser32 -lgdi32 \
          -lwinspool -lcomctl32 -luuid -lkernel32 -lws2_32 -Wl,--end-group
    

Для Unix/Linux и GNU C это будет выглядеть так:

       #!/bin/sh
       HB_INS="/apps/harbour"
       $HB_INS/bin/harbour $1.prg -n -q0 -es2 -gc0 -I$HB_INS/include -I../include -d__LINUX__
       gcc -I. -I$HB_INS/include -Wall -c $1.c -o$1.o
       gcc -Wall -o$1 $1.o $HB_INS/lib/libharbour-2.1.0.so -lm -lgpm
    
т.е. весь список библиотек мы заменили на libharbour-2.1.0.so (для другой версии Harbour название, соответственно, будет другим) - саму динамическую библиотеку, import library здесь не нужна.

С hbmk2 все существенно проще. Независимо от платформы и компилятора:

       hbmk2 hello.prg -shared
    

Теперь о другом варианте использования динамических библиотек - о так называемых p-code dll. Вы можете откомпилировать и собрать часть ваших prg в динамическую библиотеку ( dll или so ) и затем использовать ее со своими приложениями; такую динамическую библиотеку мы и называем p-code dll.

Итак, мы имеем файл mylib.prg с функцией M1(), который мы хотим собрать в виде p-code dll с тем, чтобы впоследствии использовать его с главным приложением myapp.prg:

    // mylib.prg
    FUNCTION M1
       ? "Это функция из динамической библиотеки " + Procname()
       inkey(0)
       RETURN Nil
    

Наше главное приложение myapp может быть собрано со статическими библиотеками или с Harbour dll ( so ), как было описано в начале этого подраздела. Здесь мы рассмотрим второй вариант, когда myapp собирается с Harbour dll, поскольку первый требует пересборку Harbour с ключом set HB_USER_CFLAGS=-DHB_DYNLIB. У нас есть 2 способа сборки myapp с mylib - со статическим связыванием и с динамическим связыванием. Статическое связывание динамической библиотеки - это звучит немного странно :), но я поясню, что имеется ввиду. Статическое связывание предполагает, что уже на стадии линковки ( терпеть не могу это слово, но у него недостаточно синонимов на русском ) разрешаются все ссылки на внешние функции. Как уже говорилось выше, некоторые компиляторы, в частности, Borland C, MSVC, требуют для этого предварительного создания import library - статической библиотеки со ссылками на функции в соответствующей динамической библиотеке; именно эта import library будет прилинковываться к главному приложению, чтобы обеспечить статическое связывание. При статическом связывании наличие "привязанной" динамической библиотеки необходимо для запуска программы, независимо от того, будете ли вы в текущем сеансе работы использовать функции из нее или нет; без этой библиотеки ваше приложение выдаст соответствующее предупреждение и не запустится. При динамическом связывании ссылки на внешние функции разрешаются во время исполнения, надо только перед использованием этих функций загрузить динамическую библиотеку с помощью функции hb_LibLoad(), ну и не забыть потом ее выгрузить при помощи hb_LibFree(). В этом случае наличие динамической библиотеки потребуется не при запуске программы, а в тот момент, когда будет выполняться hb_LibLoad(), если она вообще будет выполняться. При таком подходе можно сэкономить на времени загрузки программы и на занимаемой ею памяти - подгружая динамические модули только по мере необходимости.

При рассмотрении способов сборки будем пока для простоты пользоваться Hbmk2. Итак, статическое связывание. Собираем сначала саму динамическую библиотеку. Для Borland C и MSVC нам надо, как вы помните, создать еще и import library, поэтому пишем в командной строке:

       hbmk2 mylib.prg -shared -hbdynvm -nohblib -implib
    
Результатом этой команды станет появление mylib.dll и mylib.lib, где последняя и есть import library; опция "-implib" как раз указывает hbmk2 создать эту библиотеку. Для других компиляторов ( Mingw, GNU C ) пишем:
       hbmk2 mylib.prg -shared -hbdynvm -nohblib -olibmylib
    
т.е. то же самое, но без "-implib", в результате получаем на выходе libmylib.dll ( или libmylib.so для Linux GNU C ).

Теперь нам надо построить само приложение myapp, статически связав его с mylib.

    // myapp.prg
    FUNCTION Main
       hb_cdpSelect("RU866")
       M1()
       RETURN Nil
    
Делаем это следующим образом ( для Borland C и MSVC ):
       hbmk2 myapp.prg -shared -lmylib.lib
    
или ( для Mingw, GNU C ):
       hbmk2 myapp.prg -shared -L. -lmylib
    

Теперь динамическое связывание. Саму динамическую библиотку строим так же, как и для статического связывания, только нет нужды использовать "-implib", так как нам не нужна import library. А вот myapp.prg придется изменить, так как нам надо загружать динамическую библиотку при помощи hb_LibLoad():

    // myapp.prg
    DYNAMIC M1
    FUNCTION Main
       Local hLib

       hb_cdpSelect("RU866")
       hLib := hb_LibLoad( "mylib.dll" )
       if !empty( hLib )
          M1()
       endif
       hb_LibFree( hLib )
       RETURN Nil
    
Обратите внимание на строчку DYNAMIC M1. Поскольку мы не будем прилинковывать к нашей myapp.prg никакую библиотеку, а загрузим ее динамически, то для того, чтобы линкер не ругался на неразрешенные ссылки, мы должны объявить все функции из динамической библиотеки, которые мы собираемся использовать, как DYNAMIC. Строим наше приложение (заметьте, никакого упоминания mylib, т.к. она привязывается не статически во время линковки, а динамически - во время исполнения) :
       hbmk2 myapp.prg -shared
    

2.6 Как обойтись без C компилятора

Да, вы можете скомпилировать свою программу и запустить ее на исполнение и без C компилятора ! Harbour.exe может создать из вашего prg специальный p-code файл ( наподобие Fox'овского fxp ), небольшой по размеру, который можно исполнить с помощью утилиты Hbrun.exe - она входит в комплект дистрибутива.

Итак, компилируйте программу с ключом /gh ( остальный ключи - /n, /w, ... - как обычно, по необходимости ) :
      harbour.exe my.prg /gh
    
Если компиляция завершится без ошибок, вы получаете файл my.hrb и исполняете его:
      hbrun.exe my.hrb [ параметры ]
    
где параметры - это те параметры, с которыми вы запускаете свою программу.
Есть тут, правда, одно досадное ограничение: таким образом вы можете скомпилировать программу только из одного prg.

Кстати, это можно сделать и при помощи hbmk2:

      hbmk2 -gh my.prg
      hbmk2 my.hrb [ параметры ]
    

И, наконец, самый простой вариант - просто запускаете на исполнение ваш prg с помощью того же hbrun:

      hbrun.exe my.prg [ параметры ]
    

Отметим, что этот hrb файл можно запустить на исполнение и из вашей программы, можно даже вызывать и отдельные функции из hrb ( подробнее об этом см. дальше, в разделе 3.6 Работа с hrb - файлами ). И, вообще говоря, hrb файл очень схож по своему использованию с p-code dll, рассмотренными в предыдущем подразделе.



Комментариев:       ()       пред.    след.       Добавить комментарий
Длина комментария - не больше 4000 символов.
Ваше имя:

Адрес электронной почты:
(не предназначено к показу)
 
Введите текст с картинки: