Clipper, непосредственный предшественник Harbour, был создан в 1985 г. с целью повышения производительности dBase III. Для этого исходный код программы преобразовывался на стадии компиляции в байт-код, который встраивался в исполнямый файл вместе с виртуальной машиной, предназначенной для исполнения этого байт-кода. Таким образом, Clipper давал на выходе автономный exe файл, не требующий для своего запуска и выполнения внешнего интерпретатора, как в случае dBase или FoxBase ( другой популярный xBase продукт ).
В конце 80-х и начале 90-х Clipper был очень популярен, он был одним из основных средств программирования для приложений, связанных с использованием баз данных, в первую очередь бухгалтерских, управленческих, банковских. Язык модернизировался от версии к версии, добавлялись новые подсистемы. Среди последних особенно следует отметить Extend System и RDD. Extend System (система расширения) предназначена для связи с модулями, написанными на С — вызов функций, передача параметров, получение возвращаемых значений. RDD — Replaceable Database Drivers (заменяемые драйверы баз данных) — технология, которая позволяла, прилинковав взамен стандартной другую, специальную библиотеку, работать с БД другого типа, не изменив ни строчки кода. Именно так Clipper-приложения работали, например, с Novell’овским Btrieve (если кто помнит, была такая клиент-серверная не SQL СУБД).
XBase системы всегда воспринимались как предназначенные, в первую очередь, для работы с базами данных и, возможно поэтому, с ростом популярности SQL стали выходить из тренда. И если с Fox’ом все было более-менее благополучно — купившая его Microsoft сделала на его основе популярный продукт Visual Foxpro, который еще несколько лет назад (в 2006, согласно Википедии), был на почетном 12-м месте в списке TIOBE, то у Clipper дела были куда хуже. Computer Associates, которая владела им с начала 90-х, сделала ставку на другие продукты. Clipper же остался в стороне от магистрального пути, назревшие проблемы не решались, а в 1997 году Computer Associates объявила о закрытии дальнейшей его разработки, оставив пишущих на нем программистов наедине с 16-разрядной, рассчитанной на применение в среде MS-DOS системой программирования.
Многие из тех, кто задумывался о своем будущем, мигрировали на другие платформы, но остались и те, кто считал, что достоинства Clipper, будучи реализованы в современной среде программирования, будут востребованы и дальше. Были созданы несколько таких реализаций (xBase++, Clip, Harbour), об одной из которых, наиболее успешной на этот день я и поведу речь — прошу простить меня за такое длинное, но, на мой взгляд, необходимое вступление.
Итак, Harbour. Проект стартовал в 1999 году, официальный сайт — www.harbour-project.org. Текущая версия — 3.0 (stable), 3.2 (development).
Как и Clipper, Harbour транслирует исходный текст программы в байт-код, но, в отличие от своего предшественника, компилятор Harbour создает не объектные, а с файлы, которые потом надо «скормить» С компилятору. Например, вот такую простейшую функцию, выводящую приветствие на консоль:
Function Hello ? "Hello" Return Nil
он транслирует в (комментарии — мои):
// HB_FUNC определено как: // #define HB_FUNC( funcname ) HB_EXTERN_C_ HB_EXPORT HARBOUR HB_FUN_##funcname ( void ) HB_FUNC( HELLO ) { // байт-код static const HB_BYTE pcode[] = { 36,2,0,176,2,0,106,6,72,101,108,108,111,0, 20,1,36,3,0,100,110,7 }; // Вызов виртуальной машины (далее - ВМ) для выполнения байт-кода hb_vmExecute( pcode, symbols ); }
Рассмотрим байт-код подробнее:
static const HB_BYTE pcode[] = { 36,2,0, // 36 - код, за которым следует номер строки // исходного текста, в данном случае - 2 176,2,0, // 176 - помещает символ на стек ВМ, имеется // ввиду символ, представляющий функцию вывода 106,6,'H','e','l','l','o','\0', // 106 - помещает строку на стек ВМ 20,1, // 20 - ВМ должна выполнить функцию и отбросить // ее результат, 1 - количество параметров 36,3,0, // 36 - код, за которым следует номер строки // исходного текста, в данном случае - 3 100, // 100 - помещает Nil на стек ВМ 110, // 110 - ВМ должна вернуть значение с вершины стека 7 // 7 - ВМ должна завершить работу };
Ваш проект может включать исходники на Harbour (*.prg), на C, специальные объектные файлы и библиотеки. С код может быть встроен и в prg-файл, его надо заключить в #pragma BEGINDUMP… #pragma ENDDUMP и, естественно, он должен соответствовать соглашениям EXTEND SYSTEM (я упоминал о ней, когда говорил о Clipper). Ниже — пример такого симбиоза:
Function Main ? Sinus( 30 ), Sinus( 60 ) ? Return Nil #pragma BEGINDUMP #include <math.h> #include "hbapi.h" #include "hbapiitm.h" #define PI 3.14159265 // Вычисляем синус угла, заданного в градусах HB_FUNC( SINUS ) { // hb_parnd( n ) - функция EXTEND SYSTEM, принимает n-й переданный параметр // как double из Harbour функции // hb_retnd( d ) - функция EXTEND SYSTEM, возвращает double значение d // обратно в Harbour функцию hb_retnd( sin( hb_parnd( 1 ) * PI / 180 ) ); } #pragma ENDDUMP
Я не случайно уделил столько внимания С в Harbour. Расширенная ( извините за невольную тавтологию ), по сравнению с Clipper, Extend System и Item API, предоставляющая доступ из С кода к внутренним структурам Harbour, его переменным, массивам, объектам позволяют говорить о симбиозе двух языков, я считаю это одной из важнейших особенностей Harbour. Благодаря этому Harbour уже «оброс» большим количеством модулей — оболочек к разнообразным продуктам, имеющим C API и список таких модулей, как open source, так и коммерческих, постоянно растет (в настоящее время подумываю об OpenCV). Конечно же, С используется в Harbour не только для создания оболочек к готовым продуктам, но и для самостоятельных разработок — новые RDD, GUI библиотеки и др. Иногда, в контексте некоторых приложений я рассматриваю Harbour как оболочку к С коду — для облегчения реализации пользовательского интерфейса, доступа к БД и пр.
Встроенный доступ к БД, эта родовая черта xBase, — еще одна тема, которой хочется уделить особое внимание. Это, действительно, очень удобно — иметь возможность, не используя внешние СУБД, с помощью только встроенных языковых средств производить все необходимые манипуляции с базами данных — создание, модификация, пополнение, редактирование, поиск. В случае, когда количество информации, хранящейся в БД, сравнительно невелико, использовать внешнюю СУБД представляется совершенно излишним, для таких приложений и MySQL выглядит монстром (а ведь некоторые даже MS SQL ставят) — xBase подход здесь выглядит наиболее адекватным решением. Впрочем, и для больших БД Harbour может применяться (и применяется) вполне успешно.
Приведу небольшой фрагмент кода, демонстрирующий типичные конструкции доступа к данным — для тех, кто не сталкивался с xBase языками раньше. Конечно же, арсенал средств для работы с БД в Harbour гораздо богаче, чем использованный в этих нескольких строчках.
Function Test Local aStru := { {"FAMILY","C",16,0}, {"IMYA","C",16,0}, {"OTCHES","C",16,0}, ; {"TELEFON","C",10,0} } // Создаем таблицу БД mytable с ФИО и номерами телефона dbCreate( "mytable", aStru ) // Открываем mytable USE mytable // Создаем индексы по фамилии и по телефону INDEX ON FAMILY TAG FAMILY INDEX ON TELEFON TAG TELEFON // Добавляем записи APPEND BLANK REPLACE FAMILY WITH "Иванов", IMYA WITH "Игорь", OTCHES WITH "Константинович", ; TELEFON WITH "9101682020" ... // Ищем запись по номеру телефона, используя индекс ordSetFocus( "TELEFON" ) IF dbSeek( "9101682020" ) // Если запись найдена, изменяем номер REPLACE TELEFON WITH "9102875555" ENDIF ... Return Nil
Средства доступа к БД не ограничиваются стандартными. Есть RDD, написанные для клиент-серверных СУБД, как основанных на DBF ( коммерческая Advantage Database Server от Sybase и open source LetoDb ), та и SQL. Есть модули, обеспечивающие доступ посредством ODBC и ADO, есть модули для MySQL, PostgreSQL, SQLite, использующие C API этих СУБД.
В Harbour получили дальнейшее развитие все особенности Clipper, сделавшие его языком высокого уровня, на котором удобно программировать — автоматическое выделение и освобождение памяти, сборщик мусора, так называемые raw arrays, возможность компилировать и исполнять в run-time, в динамике фрагменты кода. Добавлена полноценная реализация ООП. Препроцессор, сохранив всю мощь Clipper’овского, расширен за счет некоторых конструкций, взятых из С. Впрочем, не буду перечислять здесь все новшества, а просто сошлюсь на раздел моего сайта Harbour для начинающих.
Да, я, кажется, забыл сказать, что Harbour — кроссплатформенная система с открытыми исходниками. Он существует на 32- и 64-разрядных платформах, на Windows, Linux, Unix, Mac OS X, QNX, OS/2, вроде бы и на Android, и еще на чем-то, чего я не видел.
Буду рад, если эта статья вызовет интерес. В этом случае можно будет рассмотреть какие-то аспекты более подробно.
ссылка на оригинал статьи http://habrahabr.ru/post/198618/
Добавить комментарий