30 апреля 2010

Шутки округления

   Для IP-телефонии я пользуюсь JustVoip (один из сервисов Betamax). Этот сервис отличается низкими ценами (в 2-3 раза ниже, чем у Skype) и наличием бесплатных звонков во многие страны на стационарный телефон.
   Так вот, как-то надо было мне позвонить другу в Германию. Запускаю JustVoip и звоню ему на домашний телефон – не снимает. Набираю ему на мобильный, а программа мне пишет: "Стоимость минуты 0.08€, у вас не хватает средств". Смотрю, точно на счету – 0.07€. Захожу на сайт сервиса, чтобы пополнить счет, а на сайте написано: "На счету 0.08€". А ведь это ровно стоимость минуты!
   Вот наглядный пример, когда округление суммы на счете до центов реализовано разными алгоритмами. Система одна, счет один, а клиентские программы разные и в результате различный баланс :(
   Итак, авторы программ задумайтесь над тем, чтобы алгоритмы обработки данных в рамках одной системы были одинаковыми!

27 апреля 2010

Delphi 2010: Ловим ошибки отсроченной загрузки DLL

   Как я писал раньше, Delphi 2010 научилась вызывать функций из DLL новым способом – с помощью отсроченной загрузки DLL.
   Одним из недостатков этого способа является то, что если при вызове функции произойдет ошибка, то пользователь не узнает ее причину. В случае если DLL не существует, так же как и если в DLL нет нужной функции, то сообщение в программе будет однотипным:

21 апреля 2010

Fast Reports переманивает клиентов у конкурентов

   Когда-то давно, на заре человечества, единственным и неповторимым генератором отчетов для Delphi был QuickReport (про ReportSmith даже вспоминать не будем). Он много лет входил в поставку Delphi и его изначально использовали все. Поработав с QuickReport и устав регулярно вспоминать "матерей его разработчиков" программисты стали искать ему альтернативу. Кто то пытался сам улучшить QuickReport, кто то стал генерировать отчеты в MS Word/Excel (например, я), кто то, в надежде на лучшее, украл или купил другие генераторы Report Builder или Rave Reports (или даже монстра по имени Crystal Reports), а кто то стал писать свой генератор отчетов. Одним из тех, кого не устроил QuickReport и кто начал писать свой генератор, был Александр Цыганенко – автор FastReport. Думал ли Александр в далеком 1998 году, что его генератор станет лидером рынка?
   За последние десять лет ситуация изменилась – генераторов отчетов, которые могут быть использованы в Delphi, написано уже много и на любой вкус. Поэтому рынок генераторов отчетов уже насытился и теперь начинается новая стадия борьбы за старых клиентов. Стадия, в которой главная роль отводится не программистам, а маркетологам. Компания Fast Reports, опередив своих конкурентов по функциональным возможностям их генераторов отчетов, решила дожать тех, кто сомневался в его покупке и начала акцию по переманиванию пользователей других коммерческих генераторов отчетов на FastReport. В обмен на лицензию конкурента они предлагают скидку в 20% на FastReport 4 VCL, FastReport VCL OLAP Pack, FastReport.NET и FastReport Studio. VCL-версию FastReport можно получить в обмен на Report Builder, Rave Reports, Crystal Reports и ActiveReports.
   Обидно за QuickReport. Его, классика жанра, вообще обделили вниманием. Но, думаю – это "заслужено", ни кто на просторах бывшего СССР не покупал это убожество программисткой мысли.

14 апреля 2010

Delphi 2010: Отсроченная загрузка DLL

Долгие годы программы на Delphi умели загружать DLL двумя способами: статически и динамически. В Delphi 2010 появился третий способ – отсроченная загрузка.

Сделаем простенькую DLL, которая экспортирует некую функцию, например, CalcFee:

library TestDLL;
Function CalcFee(const iID: Integer): Currency;
  begin
    Result := ...;
  end;
Exports
  CalcFee;
end.

и рассмотрим все три способа.

1. Статическая загрузка.
Это самый простой способ вызвать функцию из DLL. Для его реализации необходимо всего лишь описать внешнюю функцию:

Function CalcFee (const iID: Integer): Currency; external 'TestDLL.dll';

И после этого её можно вызывать:

fFee := CalcFee(1234)

Наша DLL загружается при запуске программы и остается загруженной до завершения ее работы.
За этой простотой скрывается большая проблема – если DLL удалить или испортить, то программа просто не запустится.


2. Динамическая загрузка.
Этот способ – более продвинутый, но требует написания значительно большего количества кода:

Var
  CalcFee: function(const iID: Integer): Currency;
  hDLL: THandle;
begin
  hDLL := LoadLibrary('TestDLL.dll');
  If hDLL <> 0
    then try
      @CalcFee := GetProcAddress(hDLL, 'CalcFee');
      If @CalcFee = nil
        then ShowMessage('В TestDLL.dll не найдена функция CalcFee')
      else fFee := CalcFee(1234);
    finally
      FreeLibrary(hDLL);
    end
    else ShowMessage('Ошибка при загрузке TestDLL.dll')

В этом коде используются функции Win32 API из Windows.pas:
  - LoadLibrary – загружаем DLL;
  - GetProcAddress – получаем адрес функции по её имени;
  - FreeLibrary – выгружаем DLL из памяти.

Динамическая загрузка позволяет загружать DLL только при необходимости и выгружать её, если она больше не нужна. Второе преимущество и более важное – это возможность обработать ошибки при загрузке DLL и вызове функции. Поэтому даже без DLL или с испорченной DLL программа будет работать. Если перед загрузкой DLL ее удалить, то получим нормальное сообщение:

3. Отсроченная загрузка
В Delphi 2010 появился третий способ вызова функций из DLL – отсроченная загрузка. Как и динамическая загрузка, она позволяет загружать DLL только при необходимости (например, для экономии ресурсов), но также как при статической загрузке, функцию достаточно лишь описать, добавив директиву delayed:

Function CalcFee(const iID: Integer): Currency; external 'TestDLL.dll' delayed;

Недостатки этого способа – это то, что DLL уже нельзя выгрузить и то, что если при вызове функции произойдет ошибка, то пользователь не узнает ее причину. В справке написано "Trying to call a delayed routine that cannot be resolved results in a run-time error (or an exception, if the SysUtils unit is loaded)". Если DLL удалить или если в DLL нет нужной функции, сообщение будет однотипным:
Если функция будет использована в консольной программе, то сообщение об ошибке будет тоже не информативным:

"Runtime error 255 at 7C812AFB "

Но спасение есть. При желании ошибки, возникающие во время загрузки DLL или вызове её функций можно перехватить и обработать с помощью процедур SetDliNotifyHook и SetDliFailureHook из юниты System.

Не знаю, как вам, но мне идея отсроченной загрузки DLL понравилась, и я буду её в будущем использовать.

08 апреля 2010

TIOBE Index: Delphi удерживает позиции

   Вчера компания TIOBE Software опубликовала апрельский индекс популярности языков программирования - TIOBE Programming Community Index. Согласно ему, язык программирования Delphi уверенно удерживает занятое в феврале 2010-го года 9-е место. По сравнению с апрелем прошлого года он поднялся с 11-го на 9-е место. При этом, начиная с 2001-го года, пики популярности Delphi были в 2004-м году: 12-е место в январе и 7-е в августе.
Delphi в TIOBE Index
   По сравнению с апрелем прошлого года рейтинг языка Pascal, опустился с 15-го на 16-е место. При этом в сентябре 2009-го он входил в дюжину лидеров и занимал 12-е место. Жалко прародителя :(
   "TIOBE Programming Community Index" обновляется один раз в месяц и основан на количестве квалифицированных инженеров, курсов и разработчиков дополнительного программного обеспечения. Для сбора этой информации используются поисковые машины (Google, MSN, Yahoo!, Wikipedia и YouTube). Для языка Delphi отслеживаются: Delphi, Kylix, Object Pascal, Free Pascal, Chrome (исключая "Google Chrome"), Oxygene, Delphi.NET и Delphi Prism.

01 апреля 2010

Embarcadero Technologies покупает бренд "Borland"

   По сообщению BusinessWeek компания Embarcadero Technologies, крупнейший производитель и поставщик платформенно-независимых инструментов для разработки, управления и оптимизации приложений и баз данных, подписала соглашение с Micro Focus International plc о приобретении эксклюзивного права на использование торговой марки "Borland" в названии продуктов линейки "Rapid Application, Web and Java™ Development Tools".
   "Мы возрождаем славное имя Borland! Когда-то "Borland" входил в тройку самых известных в мире брендов. В какой-то степени, использование "Borland" в названии наших продуктов – это возвращение к нашим корням. Borland – это бренд, в будущее которого верят многие ИТ-профессионалы!" – сказал вице-президент по связям с разработчиками и главный евангелист Embarcadero Technologies Дэвид Интерсаймон ("David I").
   С первого апреля 2010 года, слово "Borland" будет использоваться в названии всех новых версий инструментальных средств для разработки приложений компании Embarcadero Technologies: Borland® RAD Studio, Borland® Delphi, Borland® C++Builder, Borland® Delphi Prism, Borland® JBuilder, Borland® Delphi for PHP.