среда, 23 октября 2013 г.

Полезняшки. Ссылки на модули, “помогающие” нашему приложению, выносим в отдельный модуль

Не секрет, что друзья не растут в о.. что для корректного функционирования некоторых модулей, их упоминание в uses должно быть как можно раньше. Такие как: менеджер памяти, логгер исключений и другие полезности. Обычно их помещают в uses файла проекта (в dpr-файл). И (ну у меня – как правило) необходимость использования той, или иной фичи может регулироваться дефайнами {$ifdef}.

Но есть одна особенность: dpr-файл генерируется и обновляется средой Delphi. И если разместить {$ifdef} в uses dpr-файла, то такой {$ifdef} может пропасть.

Поэтому делается очень просто – создаётся юнит (назовём его, к примеру, AppExt.pas), который в своих uses перечисляет фичи и дефайны, а сам юнит добавляется первым в uses dpr-файла.

У меня такой модуль выглядит примерно так:

unit AppExt;

{$i jedi.inc}

{$ifdef RELEASE}            // FastMM, FastMove и FastCode при отладке могут мешать, поэтому используем только в релизе
  {$ifndef DELPHI2006_UP}   // Начиная с Delphi 2006 FastMM уже используется по умолчанию
    {$define use_fastmm}
  {$endif}
  {$define use_fastmove}
  {$define use_fastcode}
{$endif}

{$ifdef FullDebugMode}
  // Для выявления причин утечек памяти, необходимо использовать FastMM, который работает совместно с FastMM_FullDebugMode.dll
  {$define use_fastmm}
{$else}
  {$ifdef DEBUG}
    {$ifdef DELPHI2006_UP}
      // В режиме отладки, если не включен FullDebugMode, то просто включаем счётчик утечек, который доступен начиная с Delphi 2006
      {$define use_repmemleaks}
    {$endif}
  {$endif}
{$endif}

{$ifdef UNICODE}
  // FastCode не дружит с юникодными строками - поэтому принудительно выключаем
  {$undef use_fastcode}
{$endif}

interface

uses
  {$ifdef use_fastmm}
  FastMM4,
  {$endif}
  {$ifdef use_fastmove}
  FastMove,
  {$endif}
  {$ifdef use_fastcode}
  FastCode,
  {$endif}
  {$ifdef EUREKALOG}
  ExceptionLog,
  {$endif}
  VCLFixPack;

implementation

initialization
  {$ifdef use_repmemleaks}
  ReportMemoryLeaksOnShutdown := True;
  {$endif}
end.

Ну и конечно же, такой модуль достаточно написать всего один раз и повсеместно использовать в своих проектах.

2 коммент.:

Александр Люлин комментирует...

Ну я делаю это СОВСЕМ другими средствами.. С модели... Кодогенерацией..

Aleksey Timohin комментирует...

> Обычно их помещают в uses файла проекта (в dpr-файл). И (ну у меня – как правило) необходимость использования той, или иной фичи может регулироваться дефайнами {$ifdef}.
У меня тоже куча $ifdef-ов по проектам раскиданы. Так хорошо выносить подключение юнитов из других пакетов/проектов. А вот, когда юнит должен объявлен в этом же проекте (запись формата unit1 in 'unit1.pas') - тогда не всё так гладко и проще оставить IFDEFы в самом .DPK, .DPR файле (особенно если это dpk).

> Но есть одна особенность: dpr-файл генерируется и обновляется средой Delphi. И если разместить {$ifdef} в uses dpr-файла, то такой {$ifdef} может пропасть.
Не то что может, а постоянно пропадает. После любого добавления/удаления юнита через менеджер проектов, после переименования формы, и после изменения некоторых опций проекта. Я воспринимаю это как нелепый и ужасно раздражающий баг, с которым ничего не поделать. И единственное "лекарство" от этого бага - это в случае пропадания IFDEF-ов вручную построчно восстанавливать их из предыдущего коммита (TortoiseXXX рулит!).

Отправить комментарий

.

.