![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Сенсация! Код initialization может не выполнятся! [D7, Win2k, WinXP]
MikProg © (2006-07-11 21:37:00)Написана прога. С целью сериализации в секции initialization семи унитов регистрируется описанные в них классы через registerclass. Фенька в следующем: у меня программа работает, у клиента нет. Вставленные в секцию инициализации отладочные строки для записи в файл пишут лог в порядке инициализации модулей. В логе запуска на моей машине (XP и Win2k) отметился каждый из 7 модулей. В логе запуска того же экзешника у клиента (Win2k) отметились тольк 3 из 7 модулей !!! Это полный трындец! Я понимаю что могу грубо регистрировать классы где нибудь в одном месте, но это есть покушение на устои! Кто нибудь может объяснить?
atruhin (2006-07-13 08:59:00) [41]> [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;
Сергей М. (2006-07-13 08:50:00) [42]
> MikProg © (13.07.06 08:38) [70]
см.[13]
> ищу причины приводящие к указанному эффекту
Я как раз и привел одну из таких причин.
MikProg (2006-07-13 08:38:00) [43]
> Причем здесь "монолитный экзешник" ?
Давать советы не читая вопрос - моветон. Вы не находите?
Сергей М. (2006-07-13 08:18:00) [44]
> MikProg © (12.07.06 20:30) [65]
> Пример для монолитного экзешника?
Причем здесь "монолитный экзешник" ?
У него своя RTL, обращаясь к ней ты регистрируешь класс в соответствующей RTTI. А где-то далее по ходу работы приложения ты, к примеру, пытаешься проверить, не зарегистрирован ли этот класс в другоммодуле (в bpl или dll), который будучи собранным с инымзначением опции линкера Build With Run-Time Packages пользует другойэкз-р RTL и RTTI соответственно. Совершенно очевидно, что в такой ситуации GetClass вернет nil.
Суслик (2006-07-12 23:35:00) [45]ты все же попробуй, что я говорил. если будет ошибка, надо будет дальше разбираться :)
MikProg (2006-07-12 20:45:00) [46]
> Семество блоков 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 унитов
MikProg (2006-07-12 20:35:00) [47]
> Тут такой момент - проблема не у отвечающих, проблема у
> тебя.
Как это вы заметили. Если бы эта была проблема отвечающих они бы давали советы если не как устранить, то как локализовать проблему. А пока они (сорри народ ничего персонального) блещут эрудицией и не более.
MikProg (2006-07-12 20:30:00) [48]
> Каждая RTTI создается при инициализации каждой RTL.
Пример для монолитногоэкзешника?
Мефисто (2006-07-12 19:04:00) [49]
> MikProg © (12.07.06 10:00) [13]
Присоеденяюсь к пердыдущим коллегам.
Семество блоков try... уже должно быть на уровне рефлексов
Игорь Шевченко (2006-07-12 15:30:00) [50]MikProg © (12.07.06 14:44) [51]
Тут такой момент - проблема не у отвечающих, проблема у тебя.
Сергей М. (2006-07-12 15:15:00) [51]
> MikProg © (12.07.06 14:55) [57]
>
>
> > вникнуть в RTTI.
>
> Ну-ну. Подскажите как в монолитном экзешнике создать две
> копии RTTI.
Нунукай в другом месте.
Каждая RTTI создается при инициализации каждой RTL.
StriderMan (2006-07-12 15:05:00) [52]
> каждый раз при записи в лог такие строковые вычисления??
> ? жуть...
даже дважды....
> 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 засунуть...
MikProg (2006-07-12 15:04:00) [53]
> ЗЫ: Result:= ParamStr(0) + '.log';
вы оптимизирете отладочный код? В любом случае - спасибо, я попробую, но вряд ли это поможет. :)
StriderMan (2006-07-12 15:01:00) [54]
> Блин.
> 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 14:57:00) [55]
> С какого перепугу незарегистрированность
Почитай свои посты до полного понимания.
MikProg (2006-07-12 14:55:00) [56]
> вникнуть в RTTI.
Ну-ну. Подскажите как в монолитном экзешнике создать две копии RTTI.
Сергей М. (2006-07-12 14:54:00) [57]
> MikProg © (12.07.06 14:51) [54]
Ты с дуба упал ?)
С какого перепугу незарегистрированность некоего дельфийского класса вызовет "небезизвестный диалог "Приложение будет закрыто." ?)
MikProg (2006-07-12 14:52:00) [58]
> что же у тебя в 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;
MikProg (2006-07-12 14:51:00) [59]
> ЗЫ: Только что испытал
>
Напоминаю. Приложение не вызывает ошибок! А буде она произойдет вы об этом узнаете в любом случае или от обработчика в RTL дельфы или от винды (небезизвестный диалог "Приложение будет закрыто.")
sniknik (2006-07-12 14:50:00) [60]> В ожидании ...
не хочеш пока развеять сомнения и ответить, что же у тебя в LogFileName? привести код его определения, и сказать где это происходить.