Конечно, подразделение Borland, именовавшееся до недавнего времени CodeGear (а теперь проданное компании Embarcadero), не потратило последние пять лет впустую, хотя и пыталось «изобрести велосипед». Результаты его труда — Delphi 8 и Delphi.NET — в очередной раз подтверждают, что лучшее средство для визуальной разработки приложений под .NET — Visual Studio.NET. Кстати, по дороге к успеху на ниве .NET гибли сами по себе и от рук своих же создателей многообещающие разработки. Напомним:
-
Kylix (она вполне уверенно «дружила» с библиотекой Qt и предоставляла массу возможностей благодаря максимальной совместимости с Delphi 6/7 и переносимости программных решений);
-
C++BuilderX (амбициозная система разработки для С++, которой даже прочили возможность визуального программирования с помощью библиотеки wxWindow);
-
C# Builder (среда с самым загадочным предназ-начением);
-
Delphi for WinForms.
А вот главная декларируемая цель, «чтобы было так же удобно, как у Microsoft», либо отодвигалась на неопределенное будущее, либо попросту не поспевала за постоянно появляющимися новыми и необходимыми в работе технологиями, предлагаемыми Microsoft.
В то время, когда казалось, что монополия фирмы Borland на RAD-средства для Object Pascal останется почти незыблемой, а танцы со смертью будут продолжаться еще долго, разработчики из RemObjects Software претворили в жизнь изначальную идею Borland, просто интегрировав язык разработки Object Pascal со средой Microsoft Visual Studio.NET. Стоит заметить, что компания занимается разного рода полезными «штучками» как для Visual Studio, так и для Delphi. Однако если ранее речь шла о каком-то очередном чуде в виде всемогущей программной подложки, созданной для упрощения процесса создания бизнес-приложений, то сейчас на рынке представлен качественно новый, в чем-то даже революционный программный продукт. Фактически это вторая жизнь для Object Pascal под .NET.
Итак, после долгой преамбулы позвольте представить вашему вниманию Oxygene 3.0 — современный (т.е. без врожденной ущербности в виде тотального отставания от версий .NET) компилятор языка Object Pascal для платформ .NET и Mono. Конечно, приверженцам языка C# не стоит завидовать — не все так гладко в этом проекте, и ниже мы обсудим его недостатки.
Мне порой доводилось слышать мнение о том, что в Delphi 2005/2006 легко создавать приложения для платформ Mono и .NET. Не имею особого желания заниматься сравнительным анализом подобных возможностей, но меня приятно удивили простота, открытость и доступность технологии создания и сборки приложений для Mono (прямо из Linux) с использованием пакета Oxygene. Сразу оговорюсь, платформа Linux сама по себе не является «коньком» для Oxygene, но где еще, как не в этой ОС, можно хорошо проверить все связанное с Mono?
Кстати, чтобы успешно разрабатывать мощные кросс-платформенные приложения, необходимо сначала разобраться в терминологии. Создатели Oxygene пишут, что данный продукт, предназначенный для Microsoft .NET Framework и других вариаций CLR, дает возможность разработчикам писать управляемые (managed) приложения, используя новый язык, в основе которого лежат Паскаль и Object Pascal. Опытный разработчик сразу же догадается, что хотел сказать человек из общества, замученного стандартами, патентами, лицензиями и судами: этот чудесный язык — просто один из диалектов Object Pascal.
Переходим к действиям
Чтобы запустить на компиляцию свой первый Linux – проект, я скачал пакет RemObjects-Oxygene-3.0.11.501.tar.gz (RemObjects Oxygene Command Line Edition). Аналогичный пакет распространяется для Windows и Mac OS X.
Оказалось, что для запуска примера, использующего WinForms (который я подсмотрел в поставляемых с пакетом примерах), надо либо составить файл проекта, либо писать длинную командную строку для главного (и на этот раз единственного) исходного файла. Автор выбрал самый прямой путь.
Ниже в листинге приведен текст первой оконной программы для бесплатного командного компилятора Oxygene. Кстати, любопытно, что программа-обозрева-тель из файлового менеджера Krusader почти идеально справилась с подсветкой синтаксиса нового языка программирования, который мы обязаны называть Oxygene. Кто бы мог мечтать о такой удаче!
namespace WindowsApplication1;
interface
uses
System.Windows.Forms, System.Drawing;
type
MainForm = class(Form)
public
constructor;
class method Main;
end;
implementation
[assembly:AssemblyInformationalVersion
(“Специально для “Мира ПК“)]
[assembly:AssemblyVersion(“1.0.0.0”)]
constructor MainForm;
begin
with b: Button := new Button do begin
b.Parent := self;
b.Left := 10;
b.Top := 10;
b.Width := Width-30;
b.Height := 125;
b.Text := ‘Не дави на меня!’;
end;
self.Text := ‘Первый пример с Oxygene 3.0’;
end;
class method MainForm.Main;
begin
with lForm := new MainForm() do
Application.Run(lForm);
end;
end.
Упрощая изложение, приведу строку для сборки программы в том виде, в каком она была использована:
mono /home/Oxygene-3.0.11.501/Bin/Oxygene.
exe /home/Oxygene-3.0.11.501/PROJECT1/test1.
pas -assemblyname:test1 -ref:/usr/lib/mono/2.0/
System.Windows.Forms.dll -ref:/usr/lib/mono/2.0/
System.Drawing.dll -ref:/usr/lib/mono/2.1/
System.dll -out:/home/Oxygene-3.0.11.501/
PROJECT1/
Несмотря на немалую длину строки, ее содержание интуитивно понятно: руководит всем процессом платформа Mono, а в качестве компилятора указывается путь к Oxygene.exe. Имя сборки приводить необязательно. Далее даются ссылки на местоположение необходимых библиотек, входящих в данном случае в пакет Mono, путь для размещения готовой программы и ...маленькое волшебство, связанное с уточнением, как оказалось, важного вопроса: /2.1/System.dll. Здесь автор действовал, следуя своей интуиции, ибо компилятор отказался выполнять компиляции с настройками по умолчанию.
Естественно, программа test1.exe также запускается с использованием Mono. Ах, как бы этот процесс весело выглядел, будь он интегрирован с Monodevelop или хотя бы с Eclipse. Кстати, для работы очень не хватает хорошей документации. А подсказки к языку в бесплатном пакете для Linux отсутствуют совсем! Но выход все же есть. Я, например, постоянно держал запущенной среду Monodevelop со встроенным подсказчиком синтаксиса, чтобы не приходилось догадываться о том, что действительно умеет новый язык, и вспоминать, как вручную, с нуля, писать простейшие приложения для .NET.
Практические примеры
Теперь напишем программу посложнее, чем приведенная ранее, но для этого сначала придется скомпилировать простейшую библиотеку:
#include
int print_hello (void)
{
printf(“Добро пожаловать в библиотеку! “);
}
int sum (int a, int b)
{
return a + b;
}
Чтобы создать полноценную Linux-библиотеку, нам понадобится Makefile следующего содержания:
#Makefile
externalfunc.so: externalfunc.c
gcc -Wall -fPIC -O2 -c -o externalfunc.o
externalfunc.c
gcc -shared -Wl,-soname,externalfunc.so
-o externalfunc.so externalfunc.o
При создании этого файла автор не претендовал на истину или особую оригинальность, так что вы можете написать свой собственный.
А если вы еще не утомились и сумели собрать библиотеку externalfunc.so, то завершим наш грандиозный проект:
namespace WindowsApplication2;
interface
uses System,System.Runtime.InteropServices;
type
TMain = class
public
[DllImport (“/home/Oxygene-3.0.11.501/
PROJECT2/externalfunc.so”)]
class function sum(a,b:Integer):Integer;
external;
[DllImport (“/home/Oxygene-3.0.11.501/
PROJECT2/externalfunc.so”)]
class method print_hello(); external;
class method Main;
end;
implementation
class method TMain.Main;
begin
Console.WriteLine(sum(3,5));
print_hello();
end;
end.
В данном случае мы поступили некрасиво, в лоб указав программе на нестандартное местоположение библиотеки. Настоятельно рекомендую никогда так не делать. Итак, мы будем вызывать в программе, написанной на Oxygene, функции из внешней Linux-библиотеки. Потренировавшись на простых примерах, создадим чуть более интеллектуальную программу просто для того, чтобы продемонстрировать синтаксические особенности «невиданного зверя» Oxygene 3.0:
namespace WindowsApplication3;
interface
uses System,System.Collections;
type
TMain = class
public
class method Main;
end;
{$REGION ‘это простой класс Tuser’}
Tuser = class
private
_id:integer;
const _LastName = “Пупкин“;
public
property FirstName:string;
property LastName:string read _LastName;
function ToString():string; override;
constructor (id:integer);
method Test(aIdentifier: integer); async;
end;
{$ENDREGION}
implementation
method Tuser.Test(aIdentifier: integer);
begin
for i: integer := 0 to 4 do begin
Console.WriteLine(‘Thread ‘+aIdentifier.
ToString+’: ‘+i.ToString);
System.Threading.Thread.Sleep(100);
end;
Console.WriteLine(‘Thread ‘+aIdentifier.
ToString+’ is done.’);
end;
constructor Tuser(id:integer);
begin
_id:=id;
end;
function Tuser.ToString():string;
begin
result:=”[“+_id.ToString()+”]:FirstName =
“+FirstName+”; LastName = “+LastName;
end;
///
/// Программа без смысла
/// и с ошибкой времени выполнения, написана
///при полной Луне
///
class method TMain.Main;
var Maxi: Integer := 50;
begin
try
var USERS: array of Tuser;
var s := ‘’;
USERS := [new Tuser(14), new Tuser(7), new
Tuser(83)];
for each user:Tuser in USERS do s := s+ user.
ToString();
for i: Int32 := 0 to Maxi do USERS[i].
Test(i);
Console.WriteLine(USERS[0].ToString());
System.Threading.Thread.Sleep(1000);
except
on E: Exception do begin
Console.WriteLine(“TMain.Main error:
“+E.Message);
end;
end;
end;
end.
Согласитесь, по виду эта программа сильно напоминает незабвенный Delphi. Действительно, основные изменения по сравнению с классическим Delphi заключаются в поддержке языком Oxygene 3.0 стандартов современной платформы .NET. А для Linux данное правило еще обязательно дополняется ограничениями реализации со стороны платформы Mono, которая в свою очередь старается угнаться за .NET 3.0 и .NET 3.5. В общем, ничего вроде бы и нет, кроме бросающегося в глаза слова method. Остальные изменения связаны с поддержкой .NET, что в большей степени проявилось в возможности применять современные конструкции языка LINQ. Подробнее об этом можно прочитать в статье «CLG09 — Sequences and Queries» на сайте http://www.remobjects.com.
Перейдем к более красочной части повествования — описанию коммерческого варианта Oxygene для Windows.
Инсталлятор сам находит вашу срeду — MS Visual Studio (Oxygene поддерживает версии MSVS.NET 2005 и 2008), после чего появляется возможность создавать привычным путем программы для .NET с использованием языка Oxygene. Этот язык не просто добавляется в Visual Studio как отдельная утилита, а предоставляет разработчику практически полноценные возможности разработки современных приложений для .NET, после чего необходимость в Delphi for .NET просто отпадает.
Приобретение компилятора: за и против
Главный недостаток компилятора Oxygene как раз в том и заключается, что он всего лишь компилятор, а не самодостаточная среда для быстрой разработки приложений, и к нему требуется MS Visual Studio. Однако применение подобной программной связки может оказаться меньшей экзотикой, чем попытки создавать в постоянно устаревающем Delphi программы для заведомо несвежей версии .NET, изучать технические особенности распространения полученного ПО и надеяться на дальнейшие обновления, чтобы получить хотя бы какую-то часть от тех функциональных богатств, которые успешно используют разработчики на .NET. Поиск данного продукта в Рунете не дал результатов, а на сайте разработчика это чудо стоит 199 евро. Впрочем, есть студенческая лицензия за 39 евро. Желающие получить самый свежий релиз Oxygene 3.0, а также иметь полный доступ к следующим бета-версиям должны раскошелиться на 259 евро. Вот и все расходы, связанные непосредственно с Oxygene.
Перспективы
Уже при тестировании Oxygene 3.0 в Linux было видно, что Mono просто не успевает поддерживать все стандартные для .NET 3.0 и .NET 3.5 возможности, что в определенном смысле даже забавно... Сразу понимаешь, какой простор для творчества можно получить, работая в Visual Studio, родной для технологии .NET, под управлением Windows. В общем, коли уж нашлись когда-то любители Delphi for WinForms, то по сравнению с этим продуктом Oxygene 3.0 скорее всего покажется им просто манной небесной. Оповещая о своих планах на будущее, разработчики компилятора клянутся в верности всем новым возможностям, предоставляемым Microsoft, и одновременно намекают на то, что вероятна интеграция с Monodevelop... Нет слов — не планы, а просто сказка! Правда, неясным остается один вопрос: если компилятор для Monodevelop будет распространяться бесплатно, то о чем еще будут мечтать Delphi-разработчики, желающие написать современный мощный код для Linux?