Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.08.27;
Скачать: CL | DM;

Вниз

Сенсация! Код initialization может не выполнятся!   Найти похожие ветки 

 
MikProg ©   (2006-07-11 21:37) [0]

Написана прога. С целью сериализации в секции initialization семи унитов регистрируется описанные в них классы через registerclass. Фенька в следующем: у меня программа работает, у клиента нет. Вставленные в секцию инициализации отладочные строки для записи в файл пишут лог в порядке инициализации модулей. В логе запуска на моей машине (XP и Win2k) отметился каждый из 7 модулей. В логе запуска того же экзешника у клиента (Win2k) отметились тольк 3 из 7 модулей !!! Это полный трындец! Я понимаю что могу грубо регистрировать классы где нибудь в одном месте, но это есть покушение на устои! Кто нибудь может объяснить?


 
Мефисто   (2006-07-11 21:40) [1]

Код в студию, и возможно объясним...


 
Суслик ©   (2006-07-11 22:13) [2]

runtime пакеты используешь?


 
MikProg ©   (2006-07-11 22:19) [3]

unit RenderParameters;

initialization

 LogRecord("RenderParameters start");
 RegisterClasses([TSurfacePoint,TSurface,TBaseRenderParams,TRenderParams]);
 LogRecord("RenderParameters end");

finalization

end.

unit IGGProjectsCollection;

initialization

 LogRecord("IGGProjectsCollection start");
 RegisterClass(TFrameProjectMember);
 RegisterClass(TFrameProject);
 RegisterClass(TProjectsCollection);
 LogRecord("IGGProjectsCollection end");

finalization

end.

unit IGGPaintBoxImaged;

initialization

 LogRecord("IGGPaintBoxImaged start");
 RegisterClass(TFrameImaged);
 LogRecord("IGGPaintBoxImaged end");

finalization
 
end.

unit IGGPaintBoxImage;

initialization

 LogRecord("IGGPaintBoxImage start");
 RegisterClass(TFrameImage);
 TFrameImage.LayerClassesRegistrator(TFrameImage);
 LogRecord("IGGPaintBoxImage start");

finalization

end.

unit IGGPaintBoxShape;

initialization

 LogRecord("IGGPaintBoxShape start");
 RegisterClasses([TFramePoly,TFrameFigure,TFrameGeom,TFramePie]);

 TFramePoly.LayerClassesRegistrator(TFramePoly);
 TFrameFigure.LayerClassesRegistrator(TFrameFigure);
 TFrameGeom.LayerClassesRegistrator(TFrameGeom);
 TFramePie.LayerClassesRegistrator(TFramePie);
 LogRecord("IGGPaintBoxShape end");

finalization

end.

unit IGGPaintBoxText;

initialization

 LogRecord("IGGPaintBoxText start");
 RegisterClass(TFrameText);
 TFrameText.LayerClassesRegistrator(TFrameText);
 LogRecord("IGGPaintBoxText end");

finalization

end.

unit IGGPaintBoxDrowing;

initialization

 LogRecord("IGGPaintBoxDrowing start");
 RegisterClass(TFrameDrowing);
 TFrameDrowing.LayerClassesRegistrator(TFrameDrowing);
 LogRecord("IGGPaintBoxDrowing end");

finalization

end.

Все происходят от базового класса, который определяет  
LayerClassesRegistrator

unit LayerBase;

interface

uses
 windows, classes, unit3;

type

 TLayerBase = class;
 TLayerBaseClass = class of TLayerBase;

 TLayerItem = class (TCollectionItem)
 end;

 TLayerBase = class (TComponent)
 private
   FLayerID: cardinal;
 protected
   procedure AssignTo(Dest: TPersistent); override;
 public
   constructor Create(AOwner: TComponent); override;
   class function CreateFrom(Sample: TLayerBase): TLayerBase; virtual;
   class procedure LayerClassesRegistrator(LayerClass: TLayerBaseClass);
   class function LayerClassesCount: integer;
   class function LayerClassesItems(index: integer): TLayerBaseClass; overload;
   class function LayerClassesItems(ClassName: String): TLayerBaseClass; overload;
   property LayerID: cardinal read FLayerID;
 end;

implementation

var
 LayerClasses: array of TLayerBaseClass;
 LayerIDs: cardinal;

class procedure TLayerBase.LayerClassesRegistrator(
 LayerClass: TLayerBaseClass);
begin
 SetLength(LayerClasses,high(LayerClasses)+2);
 LayerClasses[high(LayerClasses)]:=LayerClass;
end;

class function TLayerBase.LayerClassesCount: integer;
begin
 Result:=high(LayerClasses)+1;
end;

initialization

 LayerClasses:=nil;
 LayerIDs:=0;

finalization

end.

в Dpr все выглядит вот так

uses
 Classes,
 Forms,
 Unit1 in "Ani\Unit1.pas" {Form1},
 IGG2AniEdit in "Ani\IGG2AniEdit.pas" {IGG2AniEditFrame: TFrame},
 IGGPaintBoxText in "Modules\IGGPaintBoxText.pas",
 IGGPaintBoxDrowing in "Modules\IGGPaintBoxDrowing.pas",
 IGGPaintBoxImage in "Modules\IGGPaintBoxImage.pas",
 IGGPaintBoxImaged in "Modules\IGGPaintBoxImaged.pas",
 IGGPaintBoxShape in "Modules\IGGPaintBoxShape.pas",
 GIFImage in "Utils\GIFImage.pas",
 RenderParameters in "Modules\RenderParameters.pas",
 IGGPaintBoxControls in "Modules\IGGPaintBoxControls.pas",
 IGGProjectsCollection in "Modules\IGGProjectsCollection.pas",
 Unit3 in "Unit3.pas";

{$R *.res}

begin
 Application.Initialize;
 RegisterClass(TFrameText);
 RegisterClass(TFrameDrowing);
 RegisterClasses([TFramePoly,TFrameFigure,TFrameGeom,TFramePie]);
 RegisterClasses([TSurfacePoint,TSurface,TBaseRenderParams,TRenderParams]);
 Application.CreateForm(TForm1, Form1);
 CheckRegisteredClassList;
 Application.Run;
end.


registerclass сюда всунут позже, чтобы хоть как то работало.

У меня в логе
11.07.2006 16:27:00 : Initializing parameters
11.07.2006 16:27:00 : RenderParameters start
11.07.2006 16:27:00 : RenderParameters end
11.07.2006 16:27:00 : IGGProjectsCollection start
11.07.2006 16:27:00 : IGGProjectsCollection end
11.07.2006 16:27:00 : IGGPaintBoxImaged start
11.07.2006 16:27:00 : IGGPaintBoxImaged end
11.07.2006 16:27:00 : IGGPaintBoxImage start
11.07.2006 16:27:00 : IGGPaintBoxImage start
11.07.2006 16:27:00 : IGGPaintBoxControls start
11.07.2006 16:27:00 : IGGPaintBoxControls end
11.07.2006 16:27:00 : IGGPaintBoxShape start
11.07.2006 16:27:00 : IGGPaintBoxShape end
11.07.2006 16:27:00 : IGGPaintBoxText start
11.07.2006 16:27:00 : IGGPaintBoxText end
11.07.2006 16:27:00 : IGGPaintBoxDrowing start
11.07.2006 16:27:00 : IGGPaintBoxDrowing end

У клиента в логе (на американской винде 2000)
7/11/2006 4:50:08 PM : Initializing parameters
7/11/2006 4:50:08 PM : RenderParameters start
7/11/2006 4:50:08 PM : RenderParameters end
7/11/2006 4:50:08 PM : IGGProjectsCollection start
7/11/2006 4:50:08 PM : IGGProjectsCollection end
7/11/2006 4:50:08 PM : IGGPaintBoxImaged start
7/11/2006 4:50:08 PM : IGGPaintBoxImaged end
7/11/2006 4:50:08 PM : IGGPaintBoxImage start
7/11/2006 4:50:08 PM : IGGPaintBoxImage start
7/11/2006 4:50:08 PM : IGGPaintBoxControls start
7/11/2006 4:50:08 PM : IGGPaintBoxControls end


 
MikProg ©   (2006-07-11 22:44) [4]

скомпилировано все в одном


 
Суслик ©   (2006-07-11 22:46) [5]

Чисто формальный вопрос
А где LayerBase в списке модулей?

(просто не понимаю)


 
MikProg ©   (2006-07-11 22:58) [6]

А надо? Там довольно длинная иерархия и в проект включены только модули с классами участвующими в сериализации (в которых имеется registerclass).


 
Суслик ©   (2006-07-11 23:06) [7]


> А надо

Скажу, как думаю - а фиг его знает.
Не секрет, что специфицированность некоторых аспектов Object Pascal недосточна. Бывает, что intialization не выполняется для модулей из runtime пакетов. Хоть закономерность невыполнения указанной секции мне ясна, но  я этого в доке явно не видел. Поэтому надо (имхо, есно) полагаться на подход, который сам борланд использует.


 
sniknik ©   (2006-07-11 23:12) [8]

возможно чудо "живет" в процедуре LogRecord (помню долго тут ктото такоеже чудо рекламировал (запись в несуществующий файл)... а в итоге оказалось пишет в текущую директорию, которая негарантирована, т.е. не всегда та, что надо)


 
MikProg ©   (2006-07-12 08:21) [9]

>который сам борланд использует.

А использован не он? В каких еще местах Борл размещает registerclass?

>возможно чудо "живет" в процедуре LogRecord

Добавлено позже для отладки


 
Сергей М. ©   (2006-07-12 08:41) [10]


> MikProg ©   (12.07.06 08:21) [9]


Судя по сравнению фрагментов приведенных логов, если у клиента в логе отсутствует строчка "IGGPaintBoxShape start" (и все последующие), то "чудо" живет именно в LogRecord().


 
sniknik ©   (2006-07-12 08:59) [11]

> Добавлено позже для отладки
и как это гарантирует от ошибки в ней?

с чего вообще решено, что не отрабатывает initialization? ведь если убрать  лог, то никаких доказательств этого нет, а раз это еще и добавлялось позднее для проверки то получается решение, что виновато, принято раньше. на чем основываясь? нам ничего не приведено.
надо сказать тут можно считать вовсе ничего не приведено, т.к. код оказывается проверкой домыслов (неизвестно на чем основанных. нам неизвестно. автор возможно судит по ошибке "не буду работать! © initialization" ;), то его можно откинуть, он ничего не показывает/не доказывает. плюс еще откидываем эмоции и остается - "у меня программа работает, у клиента нет" (единственный факт/значимая инфа), и для этого факта есть куча обьяснений попроще чем вера в чудо.
... тоже мне нашол "чудо", да такие "чудеса" куча народу считающих себя программистами пишут.


 
ЮЮ ©   (2006-07-12 09:15) [12]

Если программа слетела, а в файле лога нет ожидаемой информации, имхо, вовсе не следует,что она туда не "писалась", она могла просто "потеряться" из-за аварийного закрытия файла протокола = незакрытитию текстового файла


 
MikProg ©   (2006-07-12 10:00) [13]

Что вы как дети, ей богу!

>с чего вообще решено, что не отрабатывает initialization?
Бритву Оккама знаете? Потому что на вкус, запах и цвет выглядит как неотработка ВСЕГО кода initialization в определенных модулях.


procedure Unit3CheckExistance(ClNa: string);
begin
 if cf.GetClass(ClNa)=nil  then
   LogRecord(ClNa+" not exists")
 else
   LogRecord(ClNa+" exists");
end;

procedure CheckRegisteredClassList;
begin
 LogRecord("=== Registered Classes");
 cf:=TClassFinder.Create;
 Unit3CheckExistance("TProjectsCollection");
 Unit3CheckExistance("TFrameText");
 Unit3CheckExistance("TFrameDrowing");
 Unit3CheckExistance("TFrameImage");
 Unit3CheckExistance("TFrameImaged");
 Unit3CheckExistance("TFramePoly");
 Unit3CheckExistance("TFrameFigure");
 Unit3CheckExistance("TFrameGeom");
 Unit3CheckExistance("TFramePie");
 cf.Free;
 LogRecord("=== Registered Classes end");
end;


7/11/2006 5:55:51 PM : TProjectsCollection exists
7/11/2006 5:55:51 PM : TFrameText not exists
7/11/2006 5:55:51 PM : TFrameDrowing not exists
7/11/2006 5:55:51 PM : TFrameImage exists
7/11/2006 5:55:51 PM : TFrameImaged exists
7/11/2006 5:55:51 PM : TFramePoly not exists
7/11/2006 5:55:51 PM : TFrameFigure not exists
7/11/2006 5:55:51 PM : TFrameGeom not exists
7/11/2006 5:55:51 PM : TFramePie not exists

И кто вам сказал, что я ищу ошибку в коде? Я ищу причины приводящие к указанному эффекту и обсусловленные не только кодом, но и средой исполнения и наличием на компе программ третьих лиц.

>да такие "чудеса" куча народу считающих себя программистами пишут.
Поосторожней, пожалуйста. А то я пройдусь по корифействующим ламерам.

>Если программа слетела
Не слетела. Никаких эксепшанов, сообщений и пр. Нормально работает (насколько она это может при недозарегистрированных классах)

>вовсе не следует,что она туда не "писалась"

пусть только попробует! :)

procedure LogRecord(s: string);
var
 f: Text;
 oems: array [0..4096] of Char;
begin
   Assign(f,LogFileName);
   if not FileExists(LogFileName) then
     Rewrite(f)
   else
     Append(f);
   Writeln(f,DateTimeToStr(now)," : ",s);
   Close(f);
end;


 
Сергей М. ©   (2006-07-12 10:15) [14]


> MikProg ©   (12.07.06 10:00) [13]


Инф-ция тебе к размышлению - ф-ции RegisterClass[es], GetClass и иже с ними работают с конкретным экземпляром RTTI, создаваемым конкретным экземпляром RTL.
Если класс A зарегистрирован в экземпляре RTTI1  (RTL1), а класс В - в RTTI2 (RTL2), то обращения RTL1.GetClass(В) и RTL2.GetClass(А) - хоть из штанов выпрыгни - гарантированно вернут nil.


 
evvcom ©   (2006-07-12 10:16) [15]

Таблетка от [12]: использовать функцию Flush в LogRecord().
Кроме того, добавь обработчик Aplication.OnException, в нем ту же LogRecord() с выводом текста ошибки.


 
evvcom ©   (2006-07-12 10:20) [16]

> [15] evvcom ©   (12.07.06 10:16)

Ну раз открываешь и сразу закрываешь, то да, Flush излишен. :)


 
han_malign ©   (2006-07-12 10:21) [17]


> if not FileExists(LogFileName) then
>      Rewrite(f)
>    else
>      Append(f);

- есть еще такая функция - ForceDir(в разных вариациях) называется.
А семейство Assign и т.д. - как раз, с большой вероятностью, может сгенерировать exception при {$I+}. При этом, если SysUtils еще не инициализирован, то никаких VCL исключений ты и не увидишь...


 
han_malign ©   (2006-07-12 10:31) [18]

а то, что на одном компьютере работает, а на другом нет - ищи не инициализированную переменную...


 
REA   (2006-07-12 10:52) [19]

Подтверждаю - когда программировал систему plugin-ов (на bpl) эта секция вызывалась не всегда - пришлось что то где то явно прописывать.
На нескольких компьютерах не проверял, но скорее всего дело не в компьютере а в конфигурации софта.


 
Сергей М. ©   (2006-07-12 11:07) [20]


> REA   (12.07.06 10:52) [19]


Секция инициализации юнита, если она не пуста и предшествующий код не вызвал необработанных исключений, не может не вызываться - это противоречит борландовской концепции использования юнитов.


 
REA   (2006-07-12 11:15) [21]

Видимо для bpl все-таки может. Исключений не было там.


 
Плохиш ©   (2006-07-12 11:26) [22]


> >вовсе не следует,что она туда не "писалась"
>
> пусть только попробует! :)
>
> procedure LogRecord(s: string);

Осталось только выяснить, чему равно LogFileName?


 
sniknik ©   (2006-07-12 11:26) [23]

> И кто вам сказал, что я ищу ошибку в коде? Я ищу причины приводящие к указанному эффекту и обсусловленные ...
а, понятно, значит в своем коде сомнений нет, он "идеален и безупречен"... а поиск идет того "Била Гейтца" на которого можно было бы свалить вину за неработающую программу...
ну тогда ветку надо было начинать в потрепаться, а не в тематическом форуме.

> Поосторожней, пожалуйста. А то я пройдусь по корифействующим ламерам.
интересно было бы послушать... кстати корифеи то как раз легко воспринимают то что могут чегото не знать, могут ошибиться... (потому то и пишут без ошибок, что допускают их возможность у себя, и ищут их, а не там где светлее)
восприятие в штыки резонных в общемто замечаний это как раз черта воинствующих ламеров (врочем, другие разве бывают? если ламер начал задумываться и допускать свою неправоту то он уже юзер... ;)

>>вовсе не следует,что она туда не "писалась"
> пусть только попробует! :)

> procedure LogRecord(s: string);
> var
>  f: Text;
>  oems: array [0..4096] of Char;
> begin
>    Assign(f,LogFileName);
>    if not FileExists(LogFileName) then
>      Rewrite(f)
>    else
>      Append(f);
>    Writeln(f,DateTimeToStr(now)," : ",s);
>    Close(f);
> end;

опять таки, показанное не докаывает ничего... ну кроме того что у человека написавшего это ошибки очень даже возможны.
по пунктам
1. LogFileName оно указывает на конкретную директорию+файл или это просто имя файла? если файл, то вот оно "чудо" и есть (про которое я говорил), если же нет то почему не приведено? ты же вроде понял про что разговор и пытаешся этим кодом показать, что все "в ажуре"? а
2. передача строк в процедуру, судя по всему не только сдесь. мсье ничего не знает о передаче по ссылке, и что оно значит? зачам нужны var, const знаеш?
(только не надо вываливать кучу справочной инфы доказывающей что это тебе известно и раз плюнуть и "только здесь не так т.к. здесь и набивалось, для примера". не используеш значит не знаеш. а если знаеш и не используеш то это еще хуже)
3. ну то что устаревшие конструкции изпользуются (Text, Assign,) со времен паскаля, это ладно, компилится же, но лучше бы пользовался чем нибудь поновее (TextFile, AssignFile).
4. oems: array [0..4096] of Char; это зачем? явно не для того чтобы показать что код не набит сдесь, а скопирован... или он скопирован и "исковеркан" (типа только нужное показать)? ну тогда что он может показать вообще?


 
Сергей М. ©   (2006-07-12 11:30) [24]


> для bpl все-таки может


Нет, не может.


 
GrayFace ©   (2006-07-12 11:40) [25]

Суслик ©   (11.07.06 23:06) [7]
> специфицированность

А это что за зверь? :)

> Поэтому надо (имхо, есно) полагаться на подход, который сам борланд использует.

Че за подход?


 
Игорь Шевченко ©   (2006-07-12 11:49) [26]

sniknik ©   (12.07.06 11:26) [23]


> 2. передача строк в процедуру, судя по всему не только сдесь.
>  мсье ничего не знает о передаче по ссылке, и что оно значит?
>  зачам нужны var, const знаеш?


А эта...в чем принципиальная разница передачи строки в этом случае ?

PS: У некоторых глаголов на конце пишется мягкий знак.


 
sniknik ©   (2006-07-12 12:15) [27]

> А эта...в чем принципиальная разница передачи строки в этом случае ?
приципиально никакой, потому и "обьеденил", разница только в указании неменяемости второго, для твоегоже(программиста) контроля со стороны компилятора.

> PS: У некоторых глаголов на конце пишется мягкий знак.
знаю, но ничего поделать не могу... врожденная неграмотность, или писать быстро или перепроверять каждое слово (в ворде например). никакого удовольствия от общения тогда...


 
Юрий Зотов ©   (2006-07-12 12:26) [28]

> Игорь Шевченко ©   (12.07.06 11:49) [26]

> в чем принципиальная разница передачи строки в этом случае?

Создается копия строки - а зачем, если она не нужна? Впустую тратится время, впустую тратится память.


 
REA   (2006-07-12 12:28) [29]

2Сергей М. ©   (12.07.06 11:30) [24]
Не буду утверждать со стопроцентной уверенностью, но эффект был и не только в отладчике - классы в initialization секции bpl не регистрировались.
Система связей между bpl там достаточно сложная, поэтому эксперимент в чистом виде не поставить (да и времени нет).
Перенес регистрацию в initialization другого модуля (функции которого задействованы явно из другого bpl) - заработало.
Возможно этого не может быть - я лишь констатирую факт.


 
sniknik ©   (2006-07-12 12:39) [30]

Юрий Зотов ©   (12.07.06 12:26) [28]
> Создается копия строки - а зачем, если она не нужна? ...
я вообщето понял так, что Игорь про разницу между var и const.


 
Сергей М. ©   (2006-07-12 12:42) [31]


> REA   (12.07.06 12:28) [29]


> классы в initialization секции bpl не регистрировались


RegisterClass[es], выполнившаяся без исключения, гарантирует регистрацию в конкретном экз-ре RTTI.


 
han_malign ©   (2006-07-12 12:45) [32]

OFFTOP

> Создается копия строки - а зачем, если она не нужна? Впустую тратится время, впустую тратится память.

- вот уж от кого, а от вас(тебя) не ожидал...
{$H+}
Copy on change


 
Юрий Зотов ©   (2006-07-12 12:45) [33]

Кстати, о птичках. Что-то я сам в своих словах (см. [28]) засомневался и поставил маленький эксперимент:

procedure TForm1.FormCreate(Sender: TObject);
begin
 FStr := "Bill Gates"
end;

procedure WithoutVarAndConst(S: string);
begin
//  S := S + ";";
 with Form1 do
   Caption := Format("FStr: %x, S: %x", [Cardinal(Pointer(FStr)), Cardinal(Pointer(S))])
end;

procedure WithVar(var S: string);
begin
 with Form1 do
   Caption := Format("FStr: %x, S: %x", [Cardinal(Pointer(FStr)), Cardinal(Pointer(S))])
end;

procedure WithConst(const S: string);
begin
 with Form1 do
   Caption := Format("FStr: %x, S: %x", [Cardinal(Pointer(FStr)), Cardinal(Pointer(S))])
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
 WithoutVarAndConst(FStr)
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
 WithVar(FStr)
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
 WithConst(FStr)
end;

Результат - все три процедуры выдают одно и тоже. Хотя ожидалось, что процедура WithoutVarAndConst выдаст адрес копии строки, а не самой строки (как две оставшиеся). Если раскомментировать выделенную строчку, то, естественно, так и происходит - то есть, копия строки, если она нужна, создается уже при работе самой процедуры, но исходным параметром в нее приходит все же оригинал.

Ох, и не дурак же он, этот компилятор.
:о)


 
han_malign ©   (2006-07-12 12:56) [34]


> Кстати, о птичках.

- я пошел дальше и вывел RefCount - он увеличивается в WithoutVarAndConst... :)


 
Юрий Зотов ©   (2006-07-12 13:10) [35]

> han_malign ©   (12.07.06 12:56) [34]

Естественно, раз приходит оригинал.


 
MikProg ©   (2006-07-12 13:41) [36]

Мммда. А никто не хочет узнать что творится в IGGPaintBoxControls?

unit   IGGPaintBoxControls;

initialization

 LogRecord("IGGPaintBoxControls start");
 RegisterClass(TFrameMembers);
 CF_IGGControls:=RegisterClipboardFormat("IGG2Controls");
 LogRecord("IGGPaintBoxControls end");

finalization

end.


 
Сергей М. ©   (2006-07-12 13:43) [37]


> MikProg ©   (12.07.06 13:41) [36]


И что же там "криминального" творится, по-твоему ?


 
Игорь Шевченко ©   (2006-07-12 13:53) [38]


> Ох, и не дурак же он, этот компилятор.


Об том и речь. В изначально приведенном примере строка не модифицируется, отсюда резонный вопрос - какая разница, указывать const или не указывать ?


 
isasa ©   (2006-07-12 14:08) [39]

Юрий Зотов ©   (12.07.06 12:45) [33]
Ох, и не дурак же он, этот компилятор.

Так это, я тут напрягся и вспомнил, что передача параметра по значению еще со времен Турбо-Паскаля - только то, что меньше или равно длине регистра. :)
Остальное, все равно, по ссылке.


 
MikProg ©   (2006-07-12 14:09) [40]


> И что же там "криминального" творится, по-твоему ?

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


 
Суслик ©   (2006-07-12 14:13) [41]

автору
ты бы все-таки указал в списке юнитов проекта (он, насколько я понял, у тебя один - никаких пакетов) все юниты, которые ты в том числе неявно используешь.
Насколько я понял такие юниты у тебя есть.


 
Суслик ©   (2006-07-12 14:13) [42]

автору
ты бы все-таки указал в списке юнитов проекта (он, насколько я понял, у тебя один - никаких пакетов) все юниты, которые ты в том числе неявно используешь.
Насколько я понял такие юниты у тебя есть.


 
Суслик ©   (2006-07-12 14:13) [43]

автору
ты бы все-таки указал в списке юнитов проекта (он, насколько я понял, у тебя один - никаких пакетов) все юниты, которые ты в том числе неявно используешь.
Насколько я понял такие юниты у тебя есть.


 
StriderMan ©   (2006-07-12 14:15) [44]

рекомендую обернуть код в INITIALIZATION в try..finally и в finally писать в лог. так достовернее будет.


 
MikProg ©   (2006-07-12 14:20) [45]


> Насколько я понял такие юниты у тебя есть.

Придется, наверное, но не хочется (как не хочу и регистрировать классы где нибудь кроме initialization) - все они кандидаты на сборку в две-три библиотеки содержащие классы разных уровней иерархии.


 
MikProg ©   (2006-07-12 14:23) [46]


> рекомендую обернуть код в INITIALIZATION в try..finally
> и в finally писать в лог. так достовернее будет.

Достоверней чем что? Типа глобальный ExceptionHandler рантайма еще не готов?


 
StriderMan ©   (2006-07-12 14:25) [47]


> StriderMan ©   (12.07.06 14:15) [44]
> рекомендую обернуть код в INITIALIZATION в try..finally
> и в finally писать в лог. так достовернее будет.

а еще лучше так

try
   ...
except
 //пишем ошибку
end;
 //  пишем что все ОК


 
Сергей М. ©   (2006-07-12 14:36) [48]


> MikProg ©   (12.07.06 14:09) [40]



> никто не удосужился посмотреть


Поясни нам, валенкам, что мы должны были увидеть в этом коде такого, что хоть как-то намекало бы на суть твоей проблемы ..


 
sniknik ©   (2006-07-12 14:40) [49]

Игорь Шевченко ©   (12.07.06 13:53) [38]
> отсюда резонный вопрос - какая разница, указывать const или не указывать ?
для контроля "себя любимого". хотя честно не знал, что оптимизатор стал таким умным. всегда писал (и буду скорее всего ;).


 
StriderMan ©   (2006-07-12 14:42) [50]


> Aplication.OnException, в нем ту же LogRecord() с выводом
> текста ошибки


> Достоверней чем что? Типа глобальный ExceptionHandler рантайма
> еще не готов?

initialization в модулях выполняется еще до Application.Initialize, а именно на первом begin в проекте. Поэтому если там произойдет исключение, никакой Application.OnException ничего не поймает.

ЗЫ: Только что испытал


 
MikProg ©   (2006-07-12 14:44) [51]


> хоть как-то намекало бы на суть твоей проблемы ..

В ожидании полезных сведений я пока закомментировал RegisterClipboardFormat и жду вестей от клиента.


 
Сергей М. ©   (2006-07-12 14:46) [52]


> MikProg ©   (12.07.06 14:44) [51]


Комментируй хоть самого господа бога? но я рекомендую вникнуть в RTTI.


 
sniknik ©   (2006-07-12 14:50) [53]

> В ожидании ...
не хочеш пока развеять сомнения и ответить, что же у тебя в LogFileName? привести код его определения, и сказать где это происходить.


 
MikProg ©   (2006-07-12 14:51) [54]


> ЗЫ: Только что испытал
>

Напоминаю. Приложение не вызывает ошибок! А буде она произойдет вы об этом узнаете в любом случае или от обработчика в RTL дельфы или от винды (небезизвестный диалог "Приложение будет закрыто.")


 
MikProg ©   (2006-07-12 14:52) [55]


> что же у тебя в LogFileName?

Блин.
function LogFileName: string;
var
 s, s1: string;
begin
 s:=ParamStr(0);
 s1:=ExtractFileExt(s);
 Result:=copy(s,1,length(s)-length(s1))+".log";
end;


 
Сергей М. ©   (2006-07-12 14:54) [56]


> MikProg ©   (12.07.06 14:51) [54]


Ты с дуба упал ?)

С какого перепугу незарегистрированность некоего дельфийского класса вызовет "небезизвестный диалог "Приложение будет закрыто." ?)


 
MikProg ©   (2006-07-12 14:55) [57]


> вникнуть в RTTI.

Ну-ну. Подскажите как в монолитном экзешнике создать две копии RTTI.


 
MikProg ©   (2006-07-12 14:57) [58]


> С какого перепугу незарегистрированность

Почитай свои посты до полного понимания.


 
StriderMan ©   (2006-07-12 15:01) [59]


> Блин.
> function LogFileName: string;
> var
>  s, s1: string;
> begin
>  s:=ParamStr(0);
>  s1:=ExtractFileExt(s);
>  Result:=copy(s,1,length(s)-length(s1))+".log";
> end;


каждый раз при записи в лог такие строковые вычисления??? жуть...

ЗЫ: Result:= ParamStr(0) + ".log";


 
MikProg ©   (2006-07-12 15:04) [60]


> ЗЫ: Result:= ParamStr(0) + ".log";

вы оптимизирете отладочный код? В любом случае - спасибо, я попробую, но вряд ли это поможет. :)


 
StriderMan ©   (2006-07-12 15:05) [61]


> каждый раз при записи в лог такие строковые вычисления??
> ? жуть...

даже дважды....


> procedure LogRecord(s: string);
> var
>  f: Text;
>  oems: array [0..4096] of Char;
> begin
>    Assign(f,LogFileName);
>    if not FileExists(LogFileName) then
>      Rewrite(f)
>    else
>      Append(f);
>    Writeln(f,DateTimeToStr(now)," : ",s);
>    Close(f);
> end;


.. а Close надо бы в finally засунуть...


 
Сергей М. ©   (2006-07-12 15:15) [62]


> MikProg ©   (12.07.06 14:55) [57]
>
>
> > вникнуть в RTTI.
>
> Ну-ну. Подскажите как в монолитном экзешнике создать две
> копии RTTI.


Нунукай в другом месте.

Каждая RTTI создается при инициализации каждой RTL.


 
Игорь Шевченко ©   (2006-07-12 15:30) [63]

MikProg ©   (12.07.06 14:44) [51]

Тут такой момент - проблема не у отвечающих, проблема у тебя.


 
Мефисто   (2006-07-12 19:04) [64]


> MikProg ©   (12.07.06 10:00) [13]


Присоеденяюсь к пердыдущим коллегам.

Семество блоков try... уже должно быть на уровне рефлексов


 
MikProg ©   (2006-07-12 20:30) [65]


> Каждая RTTI создается при инициализации каждой RTL.

Пример для монолитного экзешника?


 
MikProg ©   (2006-07-12 20:35) [66]


> Тут такой момент - проблема не у отвечающих, проблема у
> тебя.

Как это вы заметили. Если бы эта была проблема отвечающих они бы давали советы если не как устранить, то как локализовать проблему. А пока они (сорри народ ничего персонального) блещут эрудицией и не более.


 
MikProg ©   (2006-07-12 20:45) [67]


> Семество блоков try... уже должно быть на уровне рефлексов

т.е. подразумевается, что дельфа может еще и маскировать ошибки?

а как же вот это

procedure       _StartExe(InitTable: PackageInfo; Module: PLibModule);
begin
 RaiseExceptionProc := @RaiseException;
 RTLUnwindProc := @RTLUnwind;
{$ENDIF}
 InitContext.InitTable := InitTable;
 InitContext.InitCount := 0;
 InitContext.Module := Module;
 MainInstance := Module.Instance;
{$IFNDEF PC_MAPPED_EXCEPTIONS}
 SetExceptionHandler;
{$ENDIF}
 IsLibrary := False;
 InitUnits;
end;

и

procedure       SetExceptionHandler;
asm
 XOR     EDX,EDX                 { using [EDX] saves some space over [0] }
 LEA     EAX,[EBP-12]
 MOV     ECX,FS:[EDX]            { ECX := head of chain                  }
 MOV     FS:[EDX],EAX            { head of chain := @exRegRec            }

 MOV     [EAX].TExcFrame.next,ECX
{$IFDEF PIC}
 LEA     EDX, [EBX]._ExceptionHandler
 MOV     [EAX].TExcFrame.desc, EDX
{$ELSE}
 MOV     [EAX].TExcFrame.desc,offset _ExceptionHandler
{$ENDIF}
 MOV     [EAX].TExcFrame.hEBP,EBP
{$IFDEF PIC}
 MOV     [EBX].InitContext.ExcFrame,EAX
{$ELSE}
 MOV     InitContext.ExcFrame,EAX
{$ENDIF}
end;

Т.е. try except уже есть вокруг всей программы. Просто обрабатка делегирована АПИ ОС

ну и далее

procedure InitUnits;
var
 Count, I: Integer;
 Table: PUnitEntryTable;
 P: Pointer;
begin
 if InitContext.InitTable = nil then
   exit;
 Count := InitContext.InitTable^.UnitCount;
 I := 0;
 Table := InitContext.InitTable^.UnitInfo;
{$IFDEF LINUX}
 Inc(Cardinal(Table), InitContext.Module^.GOT);
{$ENDIF}
 try
   while I < Count do
   begin
     P := Table^[I].Init;
     Inc(I);
     InitContext.InitCount := I;
     if Assigned(P) then
     begin
{$IFDEF LINUX}
       CallProc(P, InitContext.Module^.GOT);
{$ENDIF}
{$IFDEF MSWINDOWS}
       TProc(P)();
{$ENDIF}
     end;
   end;
 except
   FinalizeUnits;
   raise;
 end;
end;

на этом все! Далее идет код initialization унитов


 
Суслик ©   (2006-07-12 23:35) [68]

ты все же попробуй, что я говорил. если будет ошибка, надо будет дальше разбираться :)


 
Сергей М. ©   (2006-07-13 08:18) [69]


> MikProg ©   (12.07.06 20:30) [65]
> Пример для монолитного экзешника?


Причем здесь "монолитный экзешник" ?
У него своя RTL, обращаясь к ней ты регистрируешь класс в соответствующей RTTI. А где-то далее по ходу работы приложения ты, к примеру,  пытаешься проверить, не зарегистрирован ли этот класс в другом модуле (в bpl или dll), который будучи собранным с иным значением опции линкера Build With Run-Time Packages пользует другой экз-р RTL и RTTI соответственно. Совершенно очевидно, что в такой ситуации GetClass вернет nil.


 
MikProg ©   (2006-07-13 08:38) [70]


> Причем здесь "монолитный экзешник" ?

Давать советы не читая вопрос - моветон. Вы не находите?


 
Сергей М. ©   (2006-07-13 08:50) [71]


> MikProg ©   (13.07.06 08:38) [70]


см.[13]

> ищу причины приводящие к указанному эффекту


Я как раз и привел одну из таких причин.


 
atruhin ©   (2006-07-13 08:59) [72]

> [49] sniknik ©   (12.07.06 14:40)
> > отсюда резонный вопрос - какая разница, указывать const
> или не указывать ?
> для контроля "себя любимого". хотя честно не знал, что оптимизатор
> стал таким умным

Помимо вышеперечисленного большая разница во времени выполнения. При передаче БЕЗ const и var для подсчета ссылок создается неявный:
try
 
finaly
 dec(refcount);
end;
для теста можно измерить скорость выполнения(с const и без const):
function FirstByteLess (S1, S2 : string) : boolean;
begin
 result := S1[1] < S2[1];
end;


 
evvcom ©   (2006-07-13 09:44) [73]

> [39] isasa ©   (12.07.06 14:08)

Передается ссылка, но делается копия в стеке. А это уже не "по ссылке".

> [47] StriderMan ©   (12.07.06 14:25)
> try
>   ...
> except
> //пишем ошибку
> end;
> //  пишем что все ОК

Тогда уж:
try
  ...
  //  пишем что все ОК
except
  //пишем ошибку
end;

2 MikProg: и все же Assign и Rewrite я в своих проектах использовал единожды, но в конце LogRecord после всех Write[ln] делал Flush. Даже если приложение "будет закрыто" без Close файла всё записанное в нем остается.


 
REA   (2006-07-13 10:09) [74]

>RegisterClass[es], выполнившаяся без исключения, гарантирует регистрацию в конкретном экз-ре RTTI.

абсолютно да, но выполнялись они в секции инициализации которую компилятор (линкер, загрузчик bpl, или еще кто то) не вызвал.
Перенес в другую секцию инициализации другого модуля и заработало.
Если дискуссия не придет к какому то выводу и будет не лень сделаю тестовую программу.


 
Сергей М. ©   (2006-07-13 10:20) [75]


> REA   (13.07.06 10:09) [74]


> выполнялись они в секции инициализации которую компилятор
> .. не вызвал


А вот это по сей момент не факт, а лишь домыслы.
То что код секции иниц-ии не отметил себя в файле протокола, еще не говорит о невызове секции.


 
Игорь Шевченко ©   (2006-07-13 10:30) [76]

MikProg ©   (12.07.06 20:35) [66]


> Как это вы заметили. Если бы эта была проблема отвечающих
> они бы давали советы если не как устранить, то как локализовать
> проблему. А пока они (сорри народ ничего персонального)
> блещут эрудицией и не более.


http://www.ln.ua/~openxs/articles/smart-questions-ru.html

Читать наизусть.


 
isasa ©   (2006-07-13 10:40) [77]

evvcom ©   (13.07.06 09:44) [73]
Передается ссылка, но делается копия в стеке. А это уже не "по ссылке".


! Тогда как объяснить одинаковые адреса?
Юрий Зотов ©   (12.07.06 12:45) [33]

Или я чего-то непонимаю?


 
REA   (2006-07-13 11:03) [78]

>А вот это по сей момент не факт, а лишь домыслы.

А я и не говорю, что это факт - это наблюдение и повод для проверки.


 
MikProg ©   (2006-07-13 11:07) [79]


> Читать наизусть.

А можно "почитать наизусть" советы "как правильно давать ответы"? :)


 
Игорь Шевченко ©   (2006-07-13 11:10) [80]

MikProg ©   (13.07.06 11:07) [79]

Я еще раз обращаю твое внимание на то, что проблема у тебя, а не у отвечающих. И решать ее надо тебе, а не им :)


 
isasa ©   (2006-07-13 11:16) [81]

Немного изуродовал, для детализации. Разница, все таки, есть. А то я начал волноваться. :)

procedure TForm1.FormCreate(Sender: TObject);
begin
FStr := "Bill Gates";
end;

procedure WithoutVarAndConst(S: string);
begin
//  S := S + ";";
  Form1.memo1.Lines.Add(Format("@FStr: %p, @S: %p, @FStr[1]: %p, @S[1]: %p, FStr: %s, S: %s",
  [@Form1.FStr, @S, @Form1.FStr[1], @S[1], Form1.FStr, S]));
end;

procedure WithVar(var S: string);
begin
  Form1.memo1.Lines.Add(Format("@FStr: %p, @S: %p, @FStr[1]: %p, @S[1]: %p, FStr: %s, S: %s",
  [@Form1.FStr, @S, @Form1.FStr[1], @S[1], Form1.FStr, S]));
end;

procedure WithConst(const S: string);
begin
  Form1.memo1.Lines.Add(Format("@FStr: %p, @S: %p, @FStr[1]: %p, @S[1]: %p, FStr: %s, S: %s",
  [@Form1.FStr, @S, @Form1.FStr[1], @S[1], Form1.FStr, S]));
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
WithoutVarAndConst(FStr)
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
WithVar(FStr)
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
WithConst(FStr)
end;

Результат

@FStr: 008F1D40, @S: 0012F624, @FStr[1]: 008F2004, @S[1]: 008F4200, FStr: Bill Gates, S: Bill Gates
@FStr: 008F1D40, @S: 008F1D40, @FStr[1]: 008F2004, @S[1]: 008F2004, FStr: Bill Gates, S: Bill Gates
@FStr: 008F1D40, @S: 0012F624, @FStr[1]: 008F2004, @S[1]: 008F2004, FStr: Bill Gates, S: Bill Gates


 
MikProg ©   (2006-07-13 11:24) [82]


> То что код секции иниц-ии не отметил себя в файле протокола,
>  еще не говорит о невызове секции.

"код секции иниц-ии не отметил себя в файле протокола" и не произшло возникновение исключительной ситуации.

А теперь говорит?


 
MikProg ©   (2006-07-13 11:30) [83]


> И решать ее надо тебе, а не им :)

Ну и...? Че дальше то? Вы не читали хохму про "реалтайм" удаление аппендицита отоларингологом по советам в чате. Здесь все идет по тому сценарию. Пока не хватает только одного персонажа - того который все опошлит. :)


 
Сергей М. ©   (2006-07-13 11:39) [84]


> MikProg ©   (13.07.06 11:24) [82]


Цитата из справки:

..in Delphi, the application first executes the initialization section of all the units used by the application

Борланд, по-твоему, врет ?


 
Игорь Шевченко ©   (2006-07-13 11:52) [85]

MikProg ©   (13.07.06 11:30) [83]


> Ну и...? Че дальше то?


Ну эта...решай...или предоставляй всю информацию для воспроизведения своей проблемы, если кто-то захочет потратить свое драгоценное время на тебя :)


 
GrayFace ©   (2006-07-13 12:00) [86]

isasa ©   (12.07.06 14:08) [39]
Так это, я тут напрягся и вспомнил, что передача параметра по значению еще со времен Турбо-Паскаля - только то, что меньше или равно длине регистра. :)
Остальное, все равно, по ссылке.

Насколько я знаю, ShortString, массивы конечной длины и record"ы передается по значению. Впрочем, сам тестов не гонял.

MikProg ©   (12.07.06 14:52) [55]
function LogFileName: string;

Про ChangeFileExt не забывай.


 
han_malign ©   (2006-07-13 12:10) [87]

OFFTOP

> Разница, все таки, есть. А то я начал волноваться.

- разницы нет, просто ты совершаешь действие которое может потенциально привести к изменению строки(передача в функцию @s[1]), поэтому делается UniqueString(уже внутри функции)... Так что волнуйся дальше.
А неявный try finaly - действительно имеет место...


 
isasa ©   (2006-07-13 12:36) [88]

han_malign ©   (13.07.06 12:10) [87]
- разницы нет, просто ты совершаешь действие которое может потенциально привести к изменению строки(передача в функцию @s[1]), поэтому делается UniqueString(уже внутри функции)...


Это как это? Мне надо получить адрес объекта. Какая копия?
@s[1] == addr(s[1]) - использую для передачи адреса буфера, что не так.


 
han_malign ©   (2006-07-13 12:50) [89]

OFFTOP

> Это как это? Мне надо получить адрес объекта. Какая копия?

- ты этот адрес не только получаешь, но и передаешь
  procedure StrInfo(aCmnt: string; str: Pointer);
  type
    PStrRec = ^StrRec;
    StrRec = packed record
      refCnt: Longint;
      length: Longint;
    end;
  var _p: PStrRec;
  begin
     _p:= PStrRec(str);
     if(_p = nil)then Writeln(aCmnt, ": nil")
     else begin
        dec(_p);
        Writeln(aCmnt, ": [",HexDWORD(DWORD(str)),"] Ref: ", _p.refCnt)
     end;
  end;
var _s: string;
  procedure ByVal(s: string);
  begin
     StrInfo("ByValO   ", Pointer(_s));
     StrInfo("ByValP   ", Pointer(s));
     Writeln(HexDWORD(DWORD(@s[1])));
     StrInfo("ByValO~  ", Pointer(_s));
     StrInfo("ByValP~  ", Pointer(s));
  end;
OUTPUT:
ByValO   : [0083000C] Ref: 2
ByValP   : [0083000C] Ref: 2
0083001C
ByValO~  : [0083000C] Ref: 1
ByValP~  : [0083001C] Ref: 1


 
evvcom ©   (2006-07-13 12:51) [90]

> [77] isasa ©   (13.07.06 10:40)

Это частный случай шаманства оптимизатора.


 
MikProg ©   (2006-07-13 12:59) [91]


> или предоставляй всю информацию для воспроизведения своей
> проблемы,

Включите здравый смысл:
Если бы я знал в чем заключается вся информация, я бы ее уже дал.
Если добровольные помощники знали в чем заключается вся информация, то они бы ее уже запросили.
А пока имеем ... то что имеем :)
"Дохтор, у меня это!"  ©


 
MikProg ©   (2006-07-13 13:02) [92]


> Про ChangeFileExt не забывай.
>

Это глюк такой - я прекрасно знаю о ее существовании, но за последние сто лет ни разу не использовал.
"Вы хотите поговорить об этом?" ©


 
isasa ©   (2006-07-13 13:03) [93]

Ладно, утомили. :)
Не будем лезть в детали(счетчик ссылок, длина). Разница более чем в 16 байт (2 x long). Да и видно, где прямая адресация, а где косвенная.
Результат

@FStr: 008F1D40, @S: 0012F624, @FStr[1]: 008F2004, @S[1]: 008F4200, FStr: Bill Gates, S: Bill Gates
@FStr: 008F1D40, @S: 008F1D40, @FStr[1]: 008F2004, @S[1]: 008F2004, FStr: Bill Gates, S: Bill Gates
@FStr: 008F1D40, @S: 0012F624, @FStr[1]: 008F2004, @S[1]: 008F2004, FStr: Bill Gates, S: Bill Gates


 
Игорь Шевченко ©   (2006-07-13 13:05) [94]

MikProg ©   (13.07.06 12:59) [91]


> Включите здравый смысл:
> Если бы я знал в чем заключается вся информация, я бы ее
> уже дал.


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


 
Плохиш ©   (2006-07-13 13:38) [95]


> Игорь Шевченко ©   (13.07.06 13:05) [94]

Тааак долго :-( Можно всех на "слабо" развести ;-)


 
han_malign ©   (2006-07-13 14:03) [96]

OFFTOP

> Это частный случай шаманства оптимизатора.

- нет, это общий случай передачи по значению "smart pointer" динамических объектов. Оптимизатор здесь вообще не причем.

> Не будем лезть в детали(счетчик ссылок, длина). Разница
> более чем в 16 байт (2 x long). Да и видно, где прямая адресация,
>  а где косвенная.

- разница появляется ВНУТРИ функции, при передаче параметра КОПИРОВАНИЯ НЕ ПРИСХОДИТ, адресация в данном случае - всегда прямая. Строка копируется ТОЛЬКО при изменении, или действиях которые МОГУТ привести к изменению.

  procedure ByVal(s: string);
  begin
     StrInfo("ByValO   ", Pointer(_s));
     StrInfo("ByValP   ", Pointer(s));
     if(Pointer(s) <> @s[1])
     then Writeln("Pointer(s) <> @s[1]")
     else Writeln("Pointer(s) = @s[1]");

     Writeln(HexDWORD(DWORD(@s[1])));
     StrInfo("ByValO~  ", Pointer(_s));
     StrInfo("ByValP~  ", Pointer(s));
  end;
OUTPUT:
ByValO   : [0083000C] Ref: 2
ByValP   : [0083000C] Ref: 2
Pointer(s) = @s[1]
0083001C
ByValO~  : [0083000C] Ref: 1
ByValP~  : [0083001C] Ref: 1


 
MikProg ©   (2006-07-13 14:18) [97]


> Если проблема не воспроизводится, значит, проблемы нет.

Именно так я обслуживаю клиентуру за деньги. Вы же не платный саппорт? Если бы вы им были то я и разговаривал с вами по другому. А когда помогаешь по дружбе - совсем другое дело. Другу я честно отвечу "не знаю", а не начну дурить мозги что "это не баг, это фича" ©.

> дать всю информацию более опытным товарищам.

Которые, в абсолютном большинстве случаев, смогут дать ответ только если уже сталкивались с подобной хренью вживую (вы то сами верите, что господа "опытные товарищи" бросятся воспроизводить оперативную обстановку, чтобы помочь мне :) или верите что все проблемы они могут решить слегка наморщив лоб? :)) ).
Собс-но об этом и вопрос: "Кто наступал на такие грабли?" Ответ пока: 1(один) и совсем по другому поводу и его решение совпадает с моим (которое меня не удовлетворяет).


> Можно всех на "слабо" развести ;-)

Так ведь и развел. Только оно в действительности оказалось "слабо". :)


 
MikProg ©   (2006-07-13 14:21) [98]

Удалено модератором
Примечание: Offtopic


 
Игорь Шевченко ©   (2006-07-13 15:10) [99]

MikProg ©   (13.07.06 14:18) [97]


> Именно так я обслуживаю клиентуру за деньги. Вы же не платный
> саппорт?


Дорогой друг, форум точно также не является платным суппортом, ты что-то здорово перепутал. Поэтому отвечать тебе каждый волен, как ему заблагорассудится, в рамках правил этого форума.


> А когда помогаешь по дружбе - совсем другое дело.


А если не затруднит, ты не скажешь, кому ты на данном форуме успел помочь по дружбе ? :)


> Так ведь и развел. Только оно в действительности оказалось
> "слабо".


Нет, просто никому не интересно тебе помогать. Только и всего.


 
MikProg ©   (2006-07-13 16:20) [100]


> Нет, просто никому не интересно тебе помогать. Только и
> всего.
>

Зато как интересно рассказывать как бы вы мне замечательно помогли, если бы я  вел себя "правильно". Вам самому времени не жалко?


 
Игорь Шевченко ©   (2006-07-13 16:40) [101]

MikProg ©   (13.07.06 16:20) [100]


> Вам самому времени не жалко?


Я вот ссылку дал, несколькими постами раньше. Ее бы почитать неплохо, там все написано, и про мое время, в том числе :)


 
evvcom ©   (2006-07-14 09:34) [102]

> [96] han_malign ©   (13.07.06 14:03)

Посмотрел код. Действительно оптимизатор оказался не причем. Разница в вызовах с const и без const и var в вызове функции System._LStrAddRef. Но согласитесь, что string все же особенный тип. Поэтому без шаманства все же тут не обходится. Единственное в чем я ошибся, это в шамане. :) Компилятор тут колдует.
Ну а если взять "простой" тип, то при передаче по значению попросту происходит копирование параметра в стеке:
type TRec = record
 aa: Integer;
 bb: Integer;
end;

function SumWithConst(const rec: TRec): Integer;
begin
 Result := rec.aa + rec.bb;
end;

function SumWithoutVarAndConst(rec: TRec): Integer;
begin
 Result := rec.aa + rec.bb;
end;

В результате (оптимизатор выключен):
SumWithConst:begin
push ebp
mov ebp,esp
add esp,-$08
mov [ebp-$04],eax

SumWithoutVarAndConst:begin
push ebp
mov ebp,esp
add esp,-$0c
push esi
push edi
mov esi,eax
lea edi,[ebp-$08]
movsd
movsd


Вот те и копирование. Хотя никакого присвоения не происходит. Так что все-таки

> [49] sniknik ©   (12.07.06 14:40)
> не знал, что оптимизатор стал таким умным

не настолько уж он умён. Кстати и со стрингами, все же вызывается лишний раз (без const) System._LStrAddRef, хотя в коде не предполагалось никаких изменений стринга. Это адреса стрингов не изменились, но подготовка к возможному изменению все же была проведена.


 
MikProg ©   (2006-07-14 22:44) [103]

Проблема решилась включением LayerBase в проект. Чтобы это значило?


 
Игорь Шевченко ©   (2006-07-14 23:26) [104]


> Проблема решилась включением LayerBase в проект. Чтобы это
> значило?


Изменился порядок выполнения секций Initialization


 
Суслик ©   (2006-07-15 11:33) [105]


> Проблема решилась включением LayerBase в проект. Чтобы это
> значило?

1. нужно сказать спасибо Диме Тимохову :)
2. нужно запоминить, что с initialization бывают некоторые глюки, но их точно не бывает, если все используемые модуля приведены с проекте или в пакетах (если ты их используешь).

ЗЫ. На самом деле с пакетами там тоже не все просто. Ситуация (я тут о ней спрашивал но ушло в историю).
1. есть приложение А
2. есть пакет Б, который приложение А загружает с использованием loadpackage.
3. есть пакет В, который указан в секции requires пакета Б, но про него не знает ничего приложение А.
4. в пакете В есть два модуля М1 и М2.
5. М1 используется (есть в секции uses) в одном из модулей пакета Б.
6. М2 не используется ниииииигде.
В итоге секция инициализации в М2 выполнена не будет.

ЗЫЫ. Надеюсь в примере не ошибся. :)
В итоге при


 
Суслик ©   (2006-07-15 11:33) [106]


> Проблема решилась включением LayerBase в проект. Чтобы это
> значило?

1. нужно сказать спасибо Диме Тимохову :)
2. нужно запоминить, что с initialization бывают некоторые глюки, но их точно не бывает, если все используемые модуля приведены с проекте или в пакетах (если ты их используешь).

ЗЫ. На самом деле с пакетами там тоже не все просто. Ситуация (я тут о ней спрашивал но ушло в историю).
1. есть приложение А
2. есть пакет Б, который приложение А загружает с использованием loadpackage.
3. есть пакет В, который указан в секции requires пакета Б, но про него не знает ничего приложение А.
4. в пакете В есть два модуля М1 и М2.
5. М1 используется (есть в секции uses) в одном из модулей пакета Б.
6. М2 не используется ниииииигде.
В итоге секция инициализации в М2 выполнена не будет.

ЗЫЫ. Надеюсь в примере не ошибся. :)
В итоге при


 
Суслик ©   (2006-07-15 11:33) [107]


> Проблема решилась включением LayerBase в проект. Чтобы это
> значило?

1. нужно сказать спасибо Диме Тимохову :)
2. нужно запоминить, что с initialization бывают некоторые глюки, но их точно не бывает, если все используемые модуля приведены с проекте или в пакетах (если ты их используешь).

ЗЫ. На самом деле с пакетами там тоже не все просто. Ситуация (я тут о ней спрашивал но ушло в историю).
1. есть приложение А
2. есть пакет Б, который приложение А загружает с использованием loadpackage.
3. есть пакет В, который указан в секции requires пакета Б, но про него не знает ничего приложение А.
4. в пакете В есть два модуля М1 и М2.
5. М1 используется (есть в секции uses) в одном из модулей пакета Б.
6. М2 не используется ниииииигде.
В итоге секция инициализации в М2 выполнена не будет.

ЗЫЫ. Надеюсь в примере не ошибся. :)
В итоге при


 
MikProg ©   (2006-07-15 21:59) [108]


> Изменился порядок выполнения секций Initialization

Что? От порядка зависит кто вообще будет инициализирован, а кто упадет в игнор?

>  нужно запоминить, что с initialization бывают некоторые
> глюки,

Похоже я перестану их использовать. Невозможно тестировать весь код!


 
Игорь Шевченко ©   (2006-07-15 22:07) [109]

MikProg ©   (15.07.06 21:59) [108]


> Что? От порядка зависит кто вообще будет инициализирован,
>  а кто упадет в игнор?


Ты переоцениваешь мои телепатические способности - я не знаю твоего кода.


>  Невозможно тестировать весь код!


Возможно.


 
MikProg ©   (2006-07-15 23:47) [110]

Удалено модератором
Примечание: Offtopic


 
Суслик ©   (2006-07-16 00:30) [111]

Удалено модератором
Примечание: Offtopic


 
MikProg ©   (2006-07-16 09:13) [112]

Удалено модератором
Примечание: Offtopic



Страницы: 1 2 3 вся ветка

Текущий архив: 2006.08.27;
Скачать: CL | DM;

Наверх




Память: 0.83 MB
Время: 0.061 c
6-1144413083
Bryak
2006-04-07 16:31
2006.08.27
чтение из файла по сети


2-1154670842
Генадий
2006-08-04 09:54
2006.08.27
Dspack


3-1150890703
Mishenka
2006-06-21 15:51
2006.08.27
Создание динамического поля


2-1155037543
1519
2006-08-08 15:45
2006.08.27
SQL


6-1144670401
Aleksandr.
2006-04-10 16:00
2006.08.27
Как правильно приаттачить файлы для отправки через mapi?