Kylix предоставляет возможность разработки так называемых кроссплатформленных
(межплатформенных) 32-разрядных приложений, которые могут гать как в среде Linux,
так и в Windows. Для этого вы можете выбрать один из двух вариантов:
взять готовое Windows-приложение и модифицировать его с помощью средств Kylix;
создать в среде Kylix новое приложение, следуя рекомендациям, которые представлены
в данной главе.
Примечание
Большинство приложений, разработанных для работы в среде Linux (если не используются
специфичные для Linux вызовы API), могут после перекомпиляции работать под Windows.
Перенос Windows-приложений в среду Linux
Сложность переноса приложений из одной среды в другую зависит от сложности самого
приложения. Если в приложении используются специфичные вызовы функций ядра одной
из операционных систем, то перенос значительно затрудняется. Если же вы в своем
приложении используете стандартные компоненты CLX, проблемы будут возникать
значительно реже.
Итак, для переноса приложения из одной операционной системы в другую вы можете
использовать три метода.
Платформозависимый перенос. В этом случае вы перерабатываете значительную часть
кода приложения для новой операционной системы. Благодаря этому приложение будет
активизировать характерные для данной операционной системы вызовы функций ядра
и, следовательно, работать значительно быстрее.
Межплатформенный перенос. Подразумевает создание кода, который будет работоспособным как в одной, так и в другой операционной системе. В результате, несмотря на достаточную трудоемкость написания кола, получается приложение с единым интерфейсом, но разным содержанием.
Эмулирование среды Windows. Данный метод является наиболее комплексным и дорогостоящим.
Однако получившееся приложение для среды Linux будет выглядеть наиболее похожим
на переносимое из Windows приложение. Недостатком является низкая скорость выполнения
приложения при эмуляции.
Если вы переносите приложение под Linux с целью запускать его только в данной
среде, вы можете удалить все специфичные для Windows команды из приложения.
Если же вам нужно запускать приложение в обеих средах, вам придется модифицировать
код или использовать директиву компилятора $IFDEF для указания блоков кода,
специфичных для одной из сред (Linux или Windows).
Перечислим семь главных шагов, которые нужно выполнить для переноса приложения
из Windows в Linux:
1. Перенесите все исходные файлы вашего Windows-приложения на компьютер с установленной
средой Linux. Исходные файлы должны включать файлы модулей (pas), файл проекта
(dpr) и файлы используемых пакете!! (dpk). Кроме того, необходимо перенести
файлы, связанные с файлом проекта: файлы форм (dfm), файлы ресурсов (res) и
файлы опций проекта (dof). Если вы хотите откомпилировать файл только из командной
строки, вам необходим файл конфигурации (cfg).
2. Если вы планируете использование совместных ресурсов для приложении Windows
и Linux, переименуйте dfm файлы в файлы xfm, сохранив их названия (например,
переименуйте unit I.dfm в unit 1.xfm). Переименуйте ссылки на .dfm файлы в модулях
приложения из
{$R .dfm} в ($R .xfm}.
Примечание
Файлы dfm работают в среде Kylix, но после изменения могут и не работать в Delphi.
3. Смените все разделы uses с указанием правильных названий модулей Kylix (см.
далее в этой главе).
4. Перепишите код, использующий специфические для Windows процедуры, чтобы сделать
приложение более независимым от операционной системы. Сделайте это с помощью
встроенных библиотек Kylix.
5. Найдите эквиваленты для команд, которые не поддерживаются в Linux. Используйте
директиву компилятора $IFDEF (умеренно) для разграничения кода под Linux и Windows
Например, вы можете для вашего межплатформенного приложения воспользоваться
следующим кодом (листинг 21.1):
Листинг 21.1. Использование директивы $IFDEF
//Если среда - Windows
[$IFDEF MSWINDOWS]
IniFile.LoadfromFile('с:\x.txt');
[$ENDIF]
//Если среда - Kylix
[$IFDEF LINUX]
IniFile.LoadfromFile('/home/name/x.txt');
[$ENDIF]
6. Найдите ссылки на пути ко всем файлам проекта:
- укажите правильные пути ко всем файлам Linux;
- смените ссылки на имена дисковых накопителей (например, С:\);
- в местах, где вы указали множество путей, смените разделитель путей с точки
с запятой ";" на двоеточие ":";
так как имена файлов являются в Linux чувствительными к регистру, убедитесь,
что в приложении все имена файлов записаны правильно.
Примечание
Пути в Linux используют прямой слэш "/" как разделитель (например,
/usr/lib). Читатели, которые не знакомы с организацией файловой системы Linux,
могут обратиться за краткой информацией в Приложение 3 данной книги.
7. Откомпилируйте проект в Linux. Просмотрите список ошибок, которые укажут, что еще необходимо сделать для того, чтобы ваше приложение работало в среде Linux.
CLX как версия VCL
Kylix использует библиотеку компонентов Borland для создания кроссплатформенных
приложений (Borland Component Library for Cross Platform, CLX) вместо библиотеки
визуальных компонентов Delphi (Visual Component Library, VCL). В VCL многие
оконные компоненты позволяли достаточно просто работать с окнами Windows. В
среде Linux CLX обеспечивает доступ к Qt widgets (образовано от двух слов: window
- "окно" и gadget - "приспособление") при помощи специальной
библиотеки Qt. CLX очень похоже на VCL. Множество компонентов CLX имеют такие
же имена, как и в VCL. Многие свойства также имеют одинаковые названия.
Компоненты CLX можно сгруппировать в части, представленные в табл. 21.1.
Таблица 21.1. Части, в которые сгруппированы компоненты CLX
Часть | Описание |
visualCLX |
Межплатформенные графические компоненты и графика. Компоненты этой части могут различаться под Windows и Linux |
DataCLX |
Клиентские компоненты для доступа к данным. Код этих компонентов одинаков для Linux и Windows |
NetCLX | Компоненты Интернета, включающие Apache DSO и CGI WebBroker. Они одинаковы для Linux и Windows |
BaseCLX | Библиотека времени выполнения, включающая модуль Classes, pas. Код одинаков для Linux и Windows |
В VisualCLX Widgets используется вместо оконных компонентов VCL. В CLX TWidgetControl
используется как TWinControi в VCL. Другие компоненты (такие как TScroiiingwidget)
имеют соответствующие имена. Вам не нужно самостоятельно изменять TWinControl
на TWidgetControl. В файле ресурсов OControls.pas имеются объявления типов,
такие как:
TWinControl = TWidgetControl;
которые предназначены для упрощения использования компонентов разными приложениями.
Класс TWidgetControl и все его потомки имеют свойство Handle, которое представляет
собой ссылку на объект Qt, а также свойство Hooks, ссылающееся на механизм обработки
событий.
Названия модулей и расположение отдельных классов в CLX отличаются от VCL. Вам
придется самостоятельно модифицировать разделы uses для исключения модулей,
которых нет в Kylix и смены имен на имена модулей Kylix.
Отличия CLX от VCL
Хотя многое в CLX и VCL выполнено одинаково, они имеют некоторые отличия. Рассмотрим
их.
Визуальная среда Linux выглядит несколько иначе, чем Windows. Внешний вид диалоговых
окон может достаточно сильно отличаться, в зависимости от того, каким менеджером
окон вы пользуетесь в Linux (например, KDE или Gnome).
В Linux вы можете использовать свойство TApplication. style для задания внешнего
вида приложения (начертания графических элементов).
Можно оставить стиль таким, каким он установлен в Linux, но все же рекомендуется
использовать свойство style.
Весь код для работы с вариантным типом данных (variant), который находился в
модуле System, в CLX содержится в двух новых модулях:
Variants.pas;
VarUtils.pas .
Таким образом, если вы хотите использовать в своем приложении вариантные переменные,
не забудьте добавить в раздел uses модуль variants.
Среда Linux не использует для хранения информации о текущей конфигурации системы
системный реестр. Вместо него вы можете применять текстовые файлы конфигураций
и переменные среды для получения такого же эффекта, как при работе с системным
реестром Windows. Системные конфигурационные файлы в Linux часто находятся в
каталоге /etc, например /etc/hosts. Кроме того, можно сохранять информацию в
файлах инициализации ini как и в Windows. Есть лишь одно отличие: вам нужно
использовать для работы с файлами инициализации объект TMeminiFile вместо TreginiFile,
применяемого в Windows.
Нажатие клавиши <Enter> не имитирует событие щелчка кнопки мыши, как это
происходит в Delphi.
Компонент TColorDialog не имеет свойства TColorDialog.options. Таким образом,
вы не можете настроить работу и функциональность диалога выбора. Кроме того,
TColorDialog не всегда является модальным (модальным называется окно, которое
не позволяет пользователю работать с другими окнами, пока не будет закрыто).
Во время выполнения приложения комбинированные списки (TсоmbоВох) работают по-разному
в Kylix и Delphi. В Kylix вы можете добавить строку в список, введя нужный текст
строки и нажав на клавишу <Enter> для ввода комбинированного списка. Эту
опцию можно отключить, установив свойство insertMode в ciNone. Также в Kylix
можно добавить пустой (не содержащий строку) элемент списка в комбинированный
список. Если вы нажмете и будете удерживать клавишу <> на клавиатуре управления
курсором при активном комбинированном списке, то список не остановится на последней
строке как в Delphi, а будет прокручиваться опять сверху вниз.
Компонент TCustomEdit не поддерживает Undo, ClearUndo и CanUndo. Но
пользователь приложения может отменить редактирование в поле для ввода TEdit
во время работы приложения, нажав правую кнопку мыши над полем для ввода и выбрав
в выпадающем меню пункт Undo.
Значение кода клавиши <Enter> при использовании событий onKeyDown или
ОnКеуup в Windows равно 13. В Linux для этой же клавиши код имеет значение 4100.
Команды, компоненты и другие элементы, перенос
которых невозможен
Некоторые специфичные для Windows возможности не могут быть перенесены напрямую
в среду Kylix. Такие элементы, как COM, ActiveX, OLE. BDE и ADO недоступны в
среде Kylix. В табл. 21.2 перечислены элементы отличающиеся в средах Linux и
Windows, а также эквивалентные элементы Kylix, если таковые имеются.
Таблица 21.2. Различие возможностей Delphi и Kylix
Delphi/Windows возможность | Kylix/Linux возможность |
Вызовы Windows API | Методы CLX, вызовы Qt, вызовы libc или вызовы других системных библиотек |
Компоненты СОМ (включая ActiveX) | He поддерживаются |
Компоненты ADO | Компоненты доступа к базам данных |
Сообщения Windows | События Qt |
Winsock | Сокеты BSD |
Messaging Application Programming Interface (MAPI), включая стандартную библиотеку функций сообщений Windows | SMTP/POPS позволяют вам отсылать, получать и сохранять сообщения e-mail |
Компоненты наследования (компоненты, расположенные на вкладке Win 3.1 палитры компонентов) | Не поддерживаются |
В Kylix эквивалентом файлов dll Windows являются файлы библиотек разделяемых
объектов so, которые содержат независимый от расположения коя (position-independent
code, PIC). Это приводит к следующему:
переменные, которые ссылаются на абсолютные адреса в памяти, недопустимы;
ссылки на глобальную память и вызовы внешних функций должны осуществляться через
регистр ЕВХ, значение которого должно сохраняться между вызовами.
Совместимости модулей Kylix и Delphi
Все компоненты и объекты VCL и CLX определены в файлах модулей (pas). Например,
вы можете найти описание объекта TObject в модуле system.pas. а описание базового
класса TComponent - в модуле classes.pas. Когда вы помещаете объект на форму
или используете его внутри своего приложения, имя модуля, который содержит данный
компонент, помешается в раздел uses.
позволяет компилятору узнать, какие модули использует ваше приложение при работе.
В табл. 21.3 приведен список модулей Delphi и совместимых с ними модулей Cylix.
Некоторые модули Delphi имеются только в новой версии Delphi - Delphi 6.
Таблица 21.3. Совместимые модули Delphi и Kylix
Модуль Delphi |
Модуль Kylix |
ActnList |
QactnList |
Buttons | Qbuttons |
CheckLst | QcheckLst |
Classes | Classes |
Clipbrd |
Qclipbrd |
ComCtrls | QcomCtrls |
Consts |
Consts, QConsts И RTLConsts |
Contnrs | Contnrs |
Controls |
Qcontrols |
ConvUtils | ConvUtils |
DateUtils |
DateUtils |
DB | DB |
DBActns | QDBActns |
DBClient |
DBClient |
DBCommon | DBCommon |
DBConnAdmin | DBConnAdmin |
DBConsts | DBConsts |
DBCtrls | QDBCtrls |
DBGrids |
QDBGrids |
DBLocal | DBLocal |
DBLocalS |
DBLocalS |
DBLogDlg |
DBLogDlg |
DBXpress | DBXpress |
Dialogs |
Qdialogs |
DSIntf | DSIntf |
ExtCtrls | QExtCtrls |
FMTBCD | FMTBCD |
Forms | QForms |
Graphics | QGraphics |
Grids |
Qgrids |
Heiplntfs | Heiplntfs |
ImgList | QimgList |
IniFiles | IniFiles |
Mask | Qmask |
MaskUtils |
MaskUtils |
Masks | Masks |
Math | Math |
Menus | Qmenus |
Midas | Midas |
MidConst | MidConst |
Printers |
QPrinters |
Provider | Provider |
Qt | Qt |
Search | Qsearch |
Sockets | Sockets |
StdActns | QStdActns |
StdCtrls | QStdCtrls |
SqlConst |
SqlConst |
SqlExpr | SqlExpr |
SqlTimSt | SqlTimSt |
StdConvs | StdConvs |
SyncObjs | SyncObjs |
SysConst | SysConst |
Syslnit | Syslnit |
System | System |
SysUtils | SysUtils |
Types |
Types И QTypes |
Typlnfo |
Typlnfo |
VarCmplx | VarCmplx |
Variants | Variants |
VarUtils | VarUtils |
В Kylix имеются два модуля, эквивалентов для которых нет в Delphi. Это модули:
DirSei - отвечает за выбор каталога;
Qstyie - отвечает за графический интерфейс пользователя.
Табл. 21.4 содержит список модулей, которые не поддерживаются средой Kylix,
т. к. содержат объекты, специфичные для
среды Windows.
Таблица 21.4. Модули VCL, не поддерживаемые средой Kylix
Модуль VCL |
Причина, по которой он не поддерживается в Kylix |
ADOConst |
Нет ADO |
ADODB | Нет ADO |
AppEvnts | Нет объекта TapplicationEvent |
AxCtrls | Нет COM |
BdeConst | Нет BDE |
ComStrs | Нет COM |
CorbaCon | Нет Corba |
CorbaStd | Нет Corba |
CorbaVCL | Нет Corba |
CtlPanel |
Нет панели управления Windows |
DataBkr | Может появиться в более поздних версиях |
DBCGrids | Нет BDE |
DBExcept | Нет BDE |
DBInpReq | Нет BDE |
DBLookup | Устарело |
DbOleCtl | Нет СОМ |
DBPWDlg | Нет BDE |
DBTables | Нет BDE |
DdeMan | Нет DDE |
DRTable | Нет BDE |
ExtDlgs |
Нет графических диалогов |
FileCtrl | Устарело |
MConnect | Нет СОМ |
Messages | Специфичная Windows-функция |
MidasCon | Устарело |
MPlayer | Медиа-проигрыватель Windows |
Mtsobj | Нет СОМ |
MtsRdm | Нет СОМ 356 |
Mtx | Нет COM |
mxConsts | Нет COM |
ObjBrkr | Может появиться в более поздних версиях |
OleConstMay | Нет СОМ |
OleCtnrs | Нет СОМ |
OleCtrls | Нет СОМ |
OLEDB | Нет СОМ |
OleServer | Нет СОМ |
Outline | Устарело |
Registry | Специфичная для Windows поддержка системного реестра |
ScktCnst | Заменено на Sockets |
ScktComp | Заменено на Sockets |
SConnect | Неподдерживаемый протокол связи |
SvcMgr | Поддержка сервисов Windows NT |
Tabnotbk | Устарело |
Tabs | Устарело |
ToolWin | Не поддерживается |
VCLCom | Нет СОМ |
WebConst | Константы Windows |
Windows | Специфичные для Windows виртуальные коды клавиш |
Непереносимые возможности
При создании объекта CLX с помощью палитры компонентов или написания кода, использующего
метод create, компилятор создает экземпляр widget. Этот экземпляр принадлежит
данному объекту CLX. Если вы вызываете метод Free для уничтожения объекта CLX
или автоматически уничтожаете родительский контейнер, содержащий объект CLX,
экземпляр widget данного объекта будет также уничтожен. Эта функция характерна
для VCL в приложениях Windows.
Если вы создаете объект CLX с помощью метода create (AHandle), то этот объект
не будет иметь в собственности Qt widget. Таким образом, при вызове метода Free
будет уничтожен только объект CLX. В VCL Windows это невозможно.
Совместное использование файлов ресурсов
Linux и Windows
Если вы хотите, чтобы ваше приложение успешно функционировало и в Windows и
в Linux, вы можете распространять ваше приложение с ресурсными файлами, которые
необходимы как для одной, так и для другой операционной системы. Для этого вы
можете разместить файлы ресурсов на сервере, который является доступным для
обеих систем или использовать Samba на
Linux-компьютере для обеспечения доступа к файлам через сеть Microsoft.
Файлы форм (dfm в Delphi) имеют расширение xfm в Kylix. Если вы хотите использовать
один и тот же файл формы для Linux и Windows, переименуйте dfm файлы в xfm.
Иначе файлы dfm будут изменены средой Linux таким образом, что они не будут
функционировать в среде Windows.
Примечание
Переименование файлов принесет результат лишь в том случае, если вы используете
Delphi 6, которая поддерживает CLX.
Различие сред Linux и Windows
В табл. 21.5 приводится список отличий сред Linux и Windows.
Таблица 21.5. Отличия Linux и Windows
Отличие |
Описание |
Чувствительность к регистру букв в именах файлов |
В Linux заглавные буквы не являются эквивалентом прописных букв. Таким образом, файлы Test.txt и файл test.txt - разные |
Символ конца строки |
В Windows строки текста завершаются двумя байтами ASCII: 13 и 10 (перевод строки и переход на начало строки), в Linux - только одним переходом на начало строки. При переносе кода из Windows помните об этом отличии |
Символ конца текстового файла | В DOS и Windows символьное значение #26 (комбинация клавиш <Ctrl>+<Z>) распознается как конец текстового файла. Все, что находится после этого символа, не рассматривается системой как текст. Среда Linux не имеет специального символа, обозначающего конец текстового файла. Текстовые данные завершаются в конце файла |
Пакетные файлы и файлы скриптов оболочки |
Эквивалентом пакетных bat-файлов Windows в Linux являются файлы скриптов оболочки. Файлы скриптов - это текстовые файлы, содержащие инструкции и команды. Такие файлы сохраняются и делаются выполняемыми с помощью команды chmod +x <имя файла скриптах Для выполнения этого файла достаточно набрать его имя и нажать <Enter> |
Подтверждение команды |
В DOS и Windows, если вы хотите удалить файл или папку, система запрашивает подтверждение "Вы уверены, что хотите удалить файл или папку?". Linux обычно не выдает такого запроса, а просто удаляет файл или папку. Поэтому будьте особенно внимательны при удалении файлов или папок |
Обратная связь с командой | Если команда Linux выполнена успешно, будет отображена командная строка без каких-либо сообщений |
Ключи команд |
Linux использует дефис "-" для ключей команд и двойной дефис "--" - для множественных опций команды, в то время как DOS и Windows используют слэш "/" или дефис "-" |
Файлы конфигурации |
В Windows сведения о конфигурации системы хранятся в системном реестре и в файлах, таких как autoexec.bat. В Linux файлы конфигурации созданы как скрытые файлы, имена которых начинаются с точки. Многие из них находятся в каталоге /etc и в вашем домашнем каталоге /home. Кроме того, для хранения системной информации Linux использует переменные среды, такие как LD_LIBRARY_PATH (путь поиска файлов библиотек), НОМЕ (ваш домашний каталог), TERM (тип терминала: xterm, vtlOO, console), SHELL (путь к файлам оболочки), USER (ваше имя для входа в систему), PATH (список путей к файлам программ). Эти переменные определяются в оболочке или в re-файлах, например bashrc |
Динамически присоединяемые библиотеки | В Linux используются файлы разделяемых объектов so, а в Windows - файлы динамически присоединяемых библиотек dll |
Буква, обозначающая имя накопителя | В Windows для указания накопителя используется буква, например А: для накопителя на гибких дисках. В Linux такие имена не используются. Об организации файловой системы Linux см. Приложение 3 |
Исполняемые файлы | В Linux исполняемые файлы не нуждаются в расширении. В Windows такие файлы должны иметь расширение ехе Глава 21. Проблемы переноса приложений |
Расширения имен файлов | Linux не использует расширения имен файлов для определения типов файлов или для ассоциаций файлов с приложениями |
Права на файлы | В Linux с файлами и каталогами сопоставлены
права на чтение, запись и выполнение для владельца файлов, групп пользователей
и отдельных пользователей. Например, -rwxr-xr-x обозначает "слева направо": - - тип файла (- - обычный файл, d - директорий, I - ссылка); rwx - права для владельца файла (г - чтение, w - запись, х-запуск); r-х - права для группы пользователей (х - выполнение, г - чтение); r-х - права для всех остальных пользователей (чтение и выполнение). Пользователь может отменить все эти права. При использовании прав убедитесь, что приложение запущено пользователем, имеющим достаточные права |
Утилита make | Утилита фирмы Borland make не доступна в среде Linux. Вместо нее вы можете использовать собственную утилиту Linux GNU make |
Многозадачность | Linux полностью поддерживает многозадачность. Вы можете запустить несколько различных программ (называемых процессами Linux) одновременно. Вы можете запустить любой из процессов в фоновом режиме. Для этого используйте символ & после имени выполняемого файла |
Пути к файлам | Для указания пути к файлу в Linux используется прямой слэш "/", в то время как в DOS и Windows используется обратный слэш "\" |
Символические ссылки | В Linux символические ссылки - это специальные файлы, которые указывают на другие файлы, расположенные на диске. Эти ссылки создаются с помощью команды In (link). В Windows эквивалентом символических ссылок являются ярлыки рабочего стола |
Написание переносимого кода
Для создания кроссплатформенного приложения следуйте приведенным ниже советам:
сократите вызов специфичных функций API Win32 или Linux или откажитесь от него
совсем, используйте вместо этого методы CLX;
устраните конструкции PostMessage и SendMessage внутри приложения;
используйте объект TMemlniFile вместо TreglniFile;
обращайте внимание на регистр символов при наименовании файлов или каталогов;
откажитесь от кода ассемблера TASM (ассемблер GNU не поддерживает синтаксис
TASM);
попробуйте написать код, использующий платформонезависимые библиотеки и константы,
находящиеся в модулях system, sysutiis и других модулях, одинаковых для обеих
платформ.
Приведем пример, который позволяет использовать многобайтные символы для обеих
платформ (Windows и Linux). Среда Windows традиционно сопоставляет только два
байта каждому многобайтному символу. В Linux многобайтная кодировка символов
может содержать намного больше байтов на один символ (до шести байтов в кодировке
UTF-8). Обе платформы могут использовать одинаковую кодировку с помощью функции
strNextchar, находящейся в модуле Sysutiis. В листинге 21.2 приведен код для
среды Windows.
Листинг 21.2. Код для среды Windows
while р^ <> #0 do
begin
if p^ in LeadBytes then
inc(p) ;
inc(p);
end;
Этот код можно преобразовать в платформонезависимый, как показано в листинге 21.3.
Листинг 21.3. Платформонезависимый код
while р^ <> #0 do
begin
if р^ in LeadBytes then
p := StrNextChar (p)
else
inc(p);
end;
Если использование функций библиотек не приводит к работающему решению можно попробовать изолировать специфичный код в блоки SIFDEF. ОДНако постарайтесь ограничить число таких блоков.
Использование специальных директив
Пользование директивы компилятора $IFDEF является достаточно разумным путем
для разделения кода Windows и Linux в вашем межплатформенных приложении. Тем
не менее, использование директивы $IFDEF делает приложения более трудным для
понимания, поэтому старайтесь применять эту директиву как можно реже.
Пользуясь директивой $IFDEF, следуйте нижеприведенным указаниям:
постарайтесь не применять директиву $IFDEF без крайней необходимости. Эта директива применяется в исходном файле только после компиляции;
не используйте директиву SIFDEF в файлах пакетов (dpk). Создателям компонентов
нужно разработать два пакета для каждой из платформ без использования директивы
SIFDEF;
применяйте директиву SIFDEF MSWINDOWS для проверки того, что приложение запушено
в среде Windows. Используйте директиву $IFDEF WIN32 для определения различных
Windows-платформ, например 32- и 64-бит-ную версии Windows;
используйте директиву $IFDEF LINUX для проверки того, что приложение запущено в среде Linux;
избегайте в своих приложениях комбинации $IFNDEF/$ELSE. Пользуйтесь положительными тестами ($IFDEF/$ELSE) для лучшего понимания кода;
старайтесь использовать директивы $IFDEF MSWINDOWS и SIFDEF LINUX вместо комбинаций
$IFDEF LINUX/$ELSE или $IFDEF MSWINDOWS/$ELSE.
Приведем пример неосторожного обращения с директивой $IFDEFF (листинг21.4).
Листинг21.4. Неправильная работа директивы $IFDEF
{$IFDEF WIN32}
{132-битный код Windows размещаем здесь}
{$ELSE}
{116-битный код Windows находится здесь}
//!! По ошибке Linux может
// попробовать выполнить этот код ! ! !
{$ENDIF}
Вывод сообщений
Директива компилятора $MESSAGE позволяет вашему приложению выводить подсказки
сообщения и ошибки таким образом, как это делает компилятор:
($MESSAGE HINT I WARN I ERROR I FATAL 'строка текста'}
Тип сообщения выбирается вами из перечисленных выше. Если тип не указан, компилятор
по умолчанию будет выводить подсказку (HINT). Строка текста - это текст сообщения.
Она должна быть заключена в апострофы. Например:
{$MESSAGE 'Подсказка') // выводит подсказку
{$Message Hint 'Подсказка 2'} // тоже выводит подсказку
{$Message Warn 'Внимание!'} // выводит предупреждение
{$Message Error 'He поддерживается'} // выводит ошибку и компиляция
// продолжается
{$Message Fatal 'Фатальная ошибка'} // выводит ошибку и прерывает
// процесс компиляции
Перенос кода ассемблера в Linux
Если ваше Windows-приложение содержит код на языке ассемблера, вы, скорее всего,
не сможете использовать этот же самый код в Linux, т. к. среда Linux требует
независимый от позиции код (position-independent code, PIC).
Для использования кода ассемблера в платформо-независимом приложении вы можете
использовать директиву компилятора ($IFDEF PIC). Кроме того, вы можете пожертвовать
скоростью выполнения и переписать процедуру, написанную на ассемблере, на языке
Object Pascal.
Сообщения и системные события
Сообщения и события в Linux работают иначе, чем в Windows. Этот факт в первую
очередь влияет на процесс создания своих компонентов. Несмотря на это, большинство
компонентов и редакторов свойств переносятся в Linux достаточно легко. Так,
например, интерфейс TObject. Dispatch замечательно функционирует в Linux.
Для подмены определенного системного сообщения Windows вы можете использовать
один из методов, описанных в табл. 21.6. В этом случае вы сможете написать обработчик
метода вместо обработчика сообщения операционной системы Windows.
Таблица 21.6. Методы для подмены системных сообщений Windows
Метод | Описание |
ChangeBounds |
Используется, когда компонент, относящийся к классу TwidgetControl, изменяет свой размер. Является приблизительным аналогом системных сообщений WM_SIZE и WM_MOVE в Windows |
ChangeScale | Вызывается автоматически при изменении размера оконного компонента. Используется для смены масштаба формы и всех ее оконных компонентов при смене разрешения экрана или размера шрифта. Так как этот метод изменяет значения свойств тор, Left, width и Height у всех оконных компонентов, он изменяет положение компонентов и их дочерних элементов в зависимости от размеров |
ColorChanged | Вызывается в случае, когда цвет оконного компонента изменился |
CursorChanged | Вызывается, когда курсор (указатель мыши) изменяет свою форму |
EnabledChanged |
Вызывается, когда приложение изменяет состояние активности окна или оконного компонента (то есть когда изменяется значение свойства Enabled) |
FontChanged | Приблизительный аналог системного сообщения WM_FONTCHANGE в Windows. Вызывается, когда изменяется набор шрифтов |
PaletteChanged | Вызывается в случае смены системной палитры. Является приблизительным аналогом WM_PALETTECHANGED |
ShowHintChanged | Вызывается при показе и скрытии всплывающих подсказок (hints) |
StyleChanged | Вызывается при смене стиля окна или оконных
элементов GUI. Является аналогом системного сообщения WM_STYLECHANGED В Windows |
TabStopChanged | Вызывается при смене порядка обхода компонентов по клавише табуляции <ТаЬ> |
VisibleChanged | Вызывается при смене состояния видимости оконного компонента |
WidgetDestroyed | Вызывается при уничтожении окна |
Переносимые приложения баз данных
В Windows среда Delphi обеспечивает программисту три пути для доступа к информации,
содержащейся в базах данных:
ActiveX Data Objects (ADO);
Borland Database Engine (BDE);
InterBase Express.
Эти три метода не применяются в Kylix. Вместо них вы можете использовать компоненты
dbExpress, обеспечивающие новую межплатформенную технологию доступа к данным,
которая будет доступна и в Windows при использовании Delphi 6.
Прежде чем перенести приложения баз данных из Windows в Linux, вы должны понять
отличия между использованием dbExpress и механизмом доступа к данным, который
вы применяли в Windows. Эти отличия существуют на нескольких уровнях.
На самом низком уровне имеется механизм, обеспечивающий связь между вашим приложением
и сервером баз данных. Это может быть клиентская часть программного обеспечения
ADO, BDE или InterBase. Этот слой достаточно легко заменяется dbExpress, который
содержит драйверы для работы с запросами SQL.
На низком уровне вы устанавливаете на форме компоненты, которые будут использоваться
для работы с наборами данных. Эти компоненты включают компонент соединения с
базой данных, который обеспечивает подключение к серверу базы данных, и компонент
набора данных, который представляет собой выборку данных из таблиц базы данных.
Несмотря на то, что имеются некоторые достаточно важные отличия, они являются
наименее заметными на данном уровне.
На уровне интерфейса пользователя также имеются некоторые отличия. Компоненты
CLX, предназначенные для отображения данных, разработаны таким образом, чтобы
по возможности быть наиболее похожими на соответствующие компоненты Windows.
Рассмотрим эти отличия более подробно.
Отличия в dbExpress
В Linux dbExpress управляет соединением с сервером базы данных. dbExpress состоит
из набора небольших драйверов, которые поддерживают набор наиболее используемых
интерфейсов. Каждый драйвер является файлом библиотеки разделяемых объектов
(so), который может быть присоединен к вашему приложению. Так как dbExpress
был разработан как межплатформенный набор драйверов, он доступен в среде Windows
как набор динамически присоединяемых библиотек (dll).
Как и любой другой слой доступа к данным, dbExpress требует наличия клиентского
программного обеспечения, которое поставляется разработчиком базы данных. dbExpress
использует специфичный для базы данных драйвер и два конфигурационных файла:
dbxconnections и dbxdrivers. Это значительно меньше, чем вам необходимо в BDE,
который требует главную библиотеку Borland Database Engine (Idapi32.dll) плюс
специфичный драйвер для базы данных и несколько других файлов-библиотек для
поддержки базы данных.
Ниже перечислены основные отличия между dbExpress и другими слоями ступа к данным:
dbExpress обеспечивает более простой и быстрый доступ к удаленным базам данных. В результате вы можете ожидать от своего приложения быстрой скорости доступа к данным;
dbExpress может обрабатывать запросы и хранимые процедуры, но не поддерживает концепцию открытых таблиц;
dbExpress возвращает только однонаправленные указатели;
dbExpress не содержит встроенную поддержку обновления данных, кроме способности выполнения запросов INSERT, DELETE и UPDATE;
dbExpress не делает кэширования метаданных;
dbExpress выполняет исключительно запросы пользователя, тем самым оптимизируя доступ к базе данных;
dbExpress непосредственно управляет буфером записей и блоками буферов записей. В BDE для этого необходимы клиенты, чтобы распределять память, используемую для помещения записей в буфер;
dbExpress не поддерживает локальные таблицы, которые основаны не на запросах SQL (то есть такие, как Paradox, dBase или FoxPro);
драйверы dbExpress позволяют работать с базами данных InterBase, Oracle, DB2 и MySQL. Если вы используете другой сервер баз данных, вам придется выбрать один из трех путей:
- преобразовать данные в один из поддерживаемых форматов;
- написать самостоятельно драйвер dbExpress для используемого сервера баз данных;
- использовать драйвер стороннего производителя.
Отличия на уровне компонентов
Когда вы создаете приложение, использующее dbExpress, необходимо при-: менять
различные наборы компонентов доступа к данным.
В табл. 21.7 приведен список наиболее важных компонентов для работы с базами
данных, которые применяются в InterBase Express, BDE и ADO в среде Windows,
и показано их соответствие компонентам dbExpress для использования в среде Linux
и кроссплатформенных приложениях.
Таблица 21.7. Соответствие компонентов доступа к данным
Компоненты InterBase Express
|
Компоненты BDE |
Компоненты ADO |
Компоненты dbExpress |
TIBDatabase | Tdatabase | TADOConnection | TSQLConnectio |
TIBTable | Ttable | TADOTable | TSQLTable |
TIBQuery | Tquery | TADOQuery | TSQLQuery |
TIBStoredProc | TstoredProc | TADOStoredProc | TSQLStoredProc |
TIBDataSet | TADODataSet | TSQLDataSet |
Наборы Данных dbExpress (TSQLTable, TSQLQuery, TSQLStoredProc и TSQLDataSet)
являются, по сравнению со своими аналогами, более ограниченными, так, они поддерживают
не редактирование данных, а только прямое (одностороннее) перемещение по записям.
Из-за этих недостатков многие приложения dbExpress не работают напрямую с наборами
данных dbExpress. Чаще всего такие приложения соединяют наборы данных dbExpress
с клиентскими наборами данных, которые размещают записи из таблиц базы данных
в памяти и обеспечивают поддержку редактирования и перемещения по записям.
Примечание
При создании очень простых приложений вы можете воспользоваться компонентом
TSQLClientDataSet вместо соединения набора данных dbExpress с клиентским. Но
для большинства приложений рекомендуется использовать наборы данных dbExpress,
соединенные с компонентом TdientDataSet, представляющим собой клиентский набор
данных.
Отличия на уровне интерфейса пользователя
Как уже было сказано ранее, компоненты CLX, отображающие данные, разработаны
таким образом, чтобы быть наиболее похожими на соответствующие компоненты Windows.
Главные различия на уровне интерфейса пользователя возникают из-за отличий способа
предоставления данных между набором данных dbExpress и клиентским набором данных.
Если вы в своем приложении используете только набор данных dbExpress, то вы
должны согласиться с фактом, что набор данных не поддерживает редактирование
и обратное перемещение по записям. Так, например, вы должны удалить все элементы
управления, которые позволяют пользователю перемещаться на предыдущую запись
набора данных. Так как наборы данных dbExpress не заносят данные в буфер, вы
не можете отобразить таблицу данных (наподобие TDBGrid). Вы можете отображать
на экране только одну запись в данный момент времени.
Если вы связали набор данных dbExpress с клиентским набором данных, то элементы
интерфейса пользователя, связанные с редактированием и перемещением по записям,
должны работать. Все, что вам нужно в этом случае - переключить их на клиентский
набор данных. Главной проблемой будет только вопрос обновления данных, записываемых
в базу данных. По умолчанию большинство наборов данных в Windows записывают
обновленные данные на сервер базы данных автоматически, после их пересылки (например,
когда пользователь перемещается на другую запись таблицы). С другой стороны,
клиентские наборы данных всегда кэшируют все обновления данных в памяти. Для
того чтобы успешно разрешить эту проблему, прочитайте разд. "Обновление
данных в приложениях dbExpress", который представлен далее в этой главе.
Перенос приложений баз данных в Linux
Перенос готового приложения базы данных на драйверы dbExpress позволит создать
межплатформенное приложение, которое будет работать как под гением Windows,
так и под Linux. Из-за того, что dbExpress использует технологию, вам придется
произвести некоторые изменения в приложении. Трудность переноса приложения из
Windows в Linux зависит от типа используемой в приложении технологии. Наиболее
трудными для переноса являются те приложения, которые применяют специфичные
для Windows технологии, такие как ADO. Наиболее простыми для переноса являются
приложения, использующие технологию Delphi для работы с базами данных.
Осуществите восемь следующих шагов для переноса приложения из Windows в Linux:
Рассмотрите, где располагается база данных. Технология dbExpress обеспечивает драйверы для работы с базами данных Oracle, Interbase, DB2 и MySQL. Следовательно, данные должны находиться на одном из этих SQL-серверов. Если вы использовали другие серверы баз данных, вам придется преобразовать данные к одному из поддерживаемых типов. Для этого, если у вас есть Delphi 5 версии Enterprise, вы можете воспользоваться утилитой Data Pump, которая поможет преобразовать формат локальных данных таких платформ, как Paradox, dBase и FoxPro в один из поддерживаемых. (Для подробной инструкции работы с утилитой смотрите файл помощи datapump.hlp в каталоге Program Files\Common Files\Borland\Shared\BDE в Windows).
Если у вас в приложении формы, содержащие интерфейс пользователя, не изолированы
от модулей данных, которые включают в себя компоненты наборов данных и компоненты,
обеспечивающие соединение с сервером базы данных, вы можете захотеть их изолировать,
прежде чем продолжить перенос приложения из одной операционной системы в другую.
В этом случае вам нужно изолировать часть приложения, содержащую модули данных
от интерфейса пользователя. Затем формы интерфейса пользователя можно перенести
в Linux так же, как и любые обычные формы.
Дальнейшие шаги подразумевают, что вы изолировали компоненты для работы с данными
в отдельные модули данных.
Создайте новый модуль данных для хранения компонентов CLX, предназначенных для работы с данными.
Для каждого набора данных оригинального приложения добавьте отдельный набор данных dbExpress, компонент TDataSetProvider и компонент TdientDataSet. Дайте этим компонентам понятные имена. Установите свойство providerName компонента TdientDataSet аналогично имени компонента TdataSetProvider И свойство DataSet компонента TDataSetProvider в dbExpress. Смените свойство DataSet во всех компонентах для работы с данными, которые ссылались на оригинальный набор данных, так, чтобы они ссылались на клиентский набор данных.
Установите свойства нового набора данных в соответствии с оригинальным набором
данных:
- если оригинальным набором данных был компонент TTable,
TADOTable ИЛИ TIBTable, задайте свойство TableName компонента
TSQLTabie таким же, как и свойство TableName оригинального набора данных. Также
скопируйте значения всех свойств, используемых для установки типа связи и определения
индексов. Свойства, устанавливающие границы и фильтры, должны быть установлены
в клиентском наборе данных, а не в компоненте TSQLTabie;
- если оригинальным набором данных был компонент TQuery.
TADOQuery или TIBQuery, установите СВОЙСТВО SQL компонента
TSQLQuery равным значению свойства SQL оригинального набора данных. Задайте
свойство Params компонента TSQLQuery в соответствии со значением свойства Params
или Parameters оригинального набора данных. Если вы используете свойство DataSource
для установки связей, скопируйте его значение тоже;
- если оригинальным набором данных был компонент TstoredProc.
TADOStoredProc или TIBStoredProc, установите свойство StoredProcName компонента
TSQLStoredProc равным значению свойства StoredProcName или ProcedureName Оригинального
Набора данных, а свойство Params компонента TSQLStoredProc равным значению свойства
Params или Parameters оригинального набора данных.
Для всех компонентов, предназначенных для соединения с базой данных в оригиналльном
приложении (TDatabase, TIBDatabase ИЛИ TADOCormect ion), добавьте компонент
TSQLConnection в новый модуль данных. Нужно также добавить компонент TSQLConnection
для каждого сервера баз данных, с которым будет осуществляться соединение без
использования компонента соединения с базой данных (например, использующих свойство
ConnectionString в наборе данных ADO или свойство DatabaseName в наборе
данных BDE).
Для каждого набора данных dbExpress, которые созданы в четвертом шаге, установите
их свойства SQLConnection в значение компонентов TSQLConnection, соответствующих
нужной базе данных.
Для каждого компонента TSQLConnection определите информацию, необходимую для
установки связи с базой данных. Для этого щелкните дважды на компоненте TSQLConnection,
после чего появится редактор соединения (Connection Editor), и установите нужные
значения параметров.
Обновление данных в приложениях dbExpress
Приложения dbExpress используют клиентские наборы данных для обеспечения функций
редактирования данных. Когда вы размещаете отредактированные данные в клиентском
наборе данных, изменения записываются в Память и не передаются автоматически
на сервер базы данных. Если оригинальное Windows-приложение также использовало
кэширование данных в памяти, вам не потребуется вносить какие-либо изменения
в приложение для Linux.
Если оригинальное приложение не кэшировало данные, вы можете сымитировать поведение
набора данных Windows с помощью собственного кода, Который будет обновлять данные
на сервере всякий раз после их изменения. Для этого нужно написать обработчик
события AfterPost клиентского набора данных, как показано в листинге 21.5.
Листинг 21.5. Обработчик события AfterPost
procedure TForml.ClientDataSetlAfterPost(DataSet: TDataSet);
begin
with DataSet as TClientDataSet do
ApplyUpdates(I) ;
end;
Кроссплатформенные интернет-приложения
Интернет-приложения - это приложения типа клиент-сервер, которые используют
стандартные интернет-протоколы для обеспечения связи между клиентом и сервером.
Так как ваши приложения используют стандартные интернет-протоколы, вы можете
легко сделать ваше приложение межплатформенным. Например, программа - сервер
интернет-приложения соединяется с клиентом при помощи специального программного
обеспечения называемого Web-сервером. Приложение для сервера пишется обычно
под конкретную операционную систему, но может быть и межплатформенным. Клиентские
приложения обычно кросс-платформенные.
Среда Kylix позволяет вам создать приложение Web-сервера для работы под Linux.
Это такие приложения, как CGI- или Apache-серверы. В Windows вы можете создать
другие типы Web-серверов, например Microsoft Server DLLs (ISAPI), Netscape Server
DLLs (NSAPI) и приложения Windows CGI. Приложения CGI и некоторые приложения,
использующие WebBroker, могут запускаться как в Windows, так и в Linux.
Перенос интернет-приложений в среду Linux
Если у вас есть готовое интернет-приложение, которое необходимо перенести в
Linux, и оно применяет WebBroker и написано с использованием интерфейса WebBroker
без специфичных для Windows вызовов API, достаточно будет простой перекомпиляции
его в Linux, естественно, с учетом вышеописанной процедуры переноса простого
Windows-приложения в Linux.
Если ваше приложение использует ISAPI, NSAPI, Windows CGI или другие Web API,
осуществить перенос будет довольно сложно. Вам придется просматривать приложение
и преобразовывать все вызовы API в вызовы Apache или CGI. Кроме того, вам понадобится
сделать все изменения, необходимые для переноса обычного Windows-приложения
в Linux.
Итак, мы рассмотрели основные методы переноса приложений из среды Windows в
Linux. С учетом вышеизложенного материала вы можете создавать межплатформенные
приложения.
1. Электромагнитная волна (в религиозной терминологии релятивизма - "свет") имеет строго постоянную скорость 300 тыс.км/с, абсурдно не отсчитываемую ни от чего. Реально ЭМ-волны имеют разную скорость в веществе (например, ~200 тыс км/с в стекле и ~3 млн. км/с в поверхностных слоях металлов, разную скорость в эфире (см. статью "Температура эфира и красные смещения"), разную скорость для разных частот (см. статью "О скорости ЭМ-волн")
2. В релятивизме "свет" есть мифическое явление само по себе, а не физическая волна, являющаяся волнением определенной физической среды. Релятивистский "свет" - это волнение ничего в ничем. У него нет среды-носителя колебаний.
3. В релятивизме возможны манипуляции со временем (замедление), поэтому там нарушаются основополагающие для любой науки принцип причинности и принцип строгой логичности. В релятивизме при скорости света время останавливается (поэтому в нем абсурдно говорить о частоте фотона). В релятивизме возможны такие насилия над разумом, как утверждение о взаимном превышении возраста близнецов, движущихся с субсветовой скоростью, и прочие издевательства над логикой, присущие любой религии.
4. В гравитационном релятивизме (ОТО) вопреки наблюдаемым фактам утверждается об угловом отклонении ЭМ-волн в пустом пространстве под действием гравитации. Однако астрономам известно, что свет от затменных двойных звезд не подвержен такому отклонению, а те "подтверждающие теорию Эйнштейна факты", которые якобы наблюдались А. Эддингтоном в 1919 году в отношении Солнца, являются фальсификацией. Подробнее читайте в FAQ по эфирной физике.