![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Сенсация! Код initialization может не выполнятся! [D7, Win2k, WinXP]
MikProg © (2006-07-11 21:37:00)Написана прога. С целью сериализации в секции initialization семи унитов регистрируется описанные в них классы через registerclass. Фенька в следующем: у меня программа работает, у клиента нет. Вставленные в секцию инициализации отладочные строки для записи в файл пишут лог в порядке инициализации модулей. В логе запуска на моей машине (XP и Win2k) отметился каждый из 7 модулей. В логе запуска того же экзешника у клиента (Win2k) отметились тольк 3 из 7 модулей !!! Это полный трындец! Я понимаю что могу грубо регистрировать классы где нибудь в одном месте, но это есть покушение на устои! Кто нибудь может объяснить?
Юрий Зотов (2006-07-12 12:45:00) [81]Кстати, о птичках. Что-то я сам в своих словах (см. [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 выдаст адрес копии строки, а не самой строки (как две оставшиеся). Если раскомментировать выделенную строчку, то, естественно, так и происходит - то есть, копия строки, если она нужна, создается уже при работе самой процедуры, но исходным параметром в нее приходит все же оригинал.
Ох, и не дурак же он, этот компилятор.
:о)
Сергей М. (2006-07-12 12:42:00) [82]
> REA (12.07.06 12:28) [29]
> классы в initialization секции bpl не регистрировались
RegisterClass[es], выполнившаяся без исключения, гарантируетрегистрацию в конкретномэкз-ре RTTI.
sniknik (2006-07-12 12:39:00) [83]Юрий Зотов © (12.07.06 12:26) [28]
> Создается копия строки - а зачем, если она не нужна? ...
я вообщето понял так, что Игорь про разницу между var и const.
REA (2006-07-12 12:28:00) [84]2Сергей М. © (12.07.06 11:30) [24]
Не буду утверждать со стопроцентной уверенностью, но эффект был и не только в отладчике - классы в initialization секции bpl не регистрировались.
Система связей между bpl там достаточно сложная, поэтому эксперимент в чистом виде не поставить (да и времени нет).
Перенес регистрацию в initialization другого модуля (функции которого задействованы явно из другого bpl) - заработало.
Возможно этого не может быть - я лишь констатирую факт.
Юрий Зотов (2006-07-12 12:26:00) [85]> Игорь Шевченко © (12.07.06 11:49) [26]
> в чем принципиальная разница передачи строки в этом случае?
Создается копия строки - а зачем, если она не нужна? Впустую тратится время, впустую тратится память.
sniknik (2006-07-12 12:15:00) [86]> А эта...в чем принципиальная разница передачи строки в этом случае ?
приципиально никакой, потому и "обьеденил", разница только в указании неменяемости второго, для твоегоже(программиста) контроля со стороны компилятора.
> PS: У некоторых глаголов на конце пишется мягкий знак.
знаю, но ничего поделать не могу... врожденная неграмотность, или писать быстро или перепроверять каждое слово (в ворде например). никакого удовольствия от общения тогда...
Игорь Шевченко (2006-07-12 11:49:00) [87]sniknik © (12.07.06 11:26) [23]
> 2. передача строк в процедуру, судя по всему не только сдесь.
> мсье ничего не знает о передаче по ссылке, и что оно значит?
> зачам нужны var, const знаеш?
А эта...в чем принципиальная разница передачи строки в этом случае ?
PS: У некоторых глаголов на конце пишется мягкий знак.
GrayFace (2006-07-12 11:40:00) [88]Суслик © (11.07.06 23:06) [7]
> специфицированность
А это что за зверь? :)
> Поэтому надо (имхо, есно) полагаться на подход, который сам борланд использует.
Че за подход?
Сергей М. (2006-07-12 11:30:00) [89]
> для bpl все-таки может
Нет, не может.
Плохиш (2006-07-12 11:26:00) [90]
> >вовсе не следует,что она туда не "писалась"
>
> пусть только попробует! :)
>
> procedure LogRecord(s: string);
Осталось только выяснить, чему равно LogFileName?
sniknik (2006-07-12 11:26:00) [91]> И кто вам сказал, что я ищу ошибку в коде? Я ищу причины приводящие к указанному эффекту и обсусловленные ...
а, понятно, значит в своем коде сомнений нет, он "идеален и безупречен"... а поиск идет того "Била Гейтца" на которого можно было бы свалить вину за неработающую программу...
ну тогда ветку надо было начинать в потрепаться, а не в тематическом форуме.
> Поосторожней, пожалуйста. А то я пройдусь по корифействующим ламерам.
интересно было бы послушать... кстати корифеи то как раз легко воспринимают то что могут чегото не знать, могут ошибиться... (потому то и пишут без ошибок, что допускают их возможность у себя, и ищут их, а не там где светлее)
восприятие в штыки резонных в общемто замечаний это как раз черта воинствующих ламеров (врочем, другие разве бывают? если ламер начал задумываться и допускать свою неправоту то он уже юзер... ;)
>>вовсе не следует,что она туда не "писалась"
> пусть только попробует! :)
> 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; это зачем? явно не для того чтобы показать что код не набит сдесь, а скопирован... или он скопирован и "исковеркан" (типа только нужное показать)? ну тогда что он может показать вообще?
REA (2006-07-12 11:15:00) [92]Видимо для bpl все-таки может. Исключений не было там.
Сергей М. (2006-07-12 11:07:00) [93]
> REA (12.07.06 10:52) [19]
Секция инициализации юнита, если она не пуста и предшествующий код не вызвал необработанных исключений, не может не вызываться - это противоречит борландовской концепции использования юнитов.
REA (2006-07-12 10:52:00) [94]Подтверждаю - когда программировал систему plugin-ов (на bpl) эта секция вызывалась не всегда - пришлось что то где то явно прописывать.
На нескольких компьютерах не проверял, но скорее всего дело не в компьютере а в конфигурации софта.
han_malign (2006-07-12 10:31:00) [95]а то, что на одном компьютере работает, а на другом нет - ищи не инициализированную переменную...
han_malign (2006-07-12 10:21:00) [96]
> if not FileExists(LogFileName) then
> Rewrite(f)
> else
> Append(f);
- есть еще такая функция - ForceDir(в разных вариациях) называется.
А семейство Assign и т.д. - как раз, с большой вероятностью, может сгенерировать exception при {$I+}. При этом, если SysUtils еще не инициализирован, то никаких VCL исключений ты и не увидишь...
evvcom (2006-07-12 10:20:00) [97]> [15] evvcom © (12.07.06 10:16)
Ну раз открываешь и сразу закрываешь, то да, Flush излишен. :)
evvcom (2006-07-12 10:16:00) [98]Таблетка от [12]: использовать функцию Flush в LogRecord().
Кроме того, добавь обработчик Aplication.OnException, в нем ту же LogRecord() с выводом текста ошибки.
Сергей М. (2006-07-12 10:15:00) [99]
> MikProg © (12.07.06 10:00) [13]
Инф-ция тебе к размышлению - ф-ции RegisterClass[es], GetClass и иже с ними работают с конкретным экземпляром RTTI, создаваемым конкретным экземпляром RTL.
Если класс A зарегистрирован в экземпляре RTTI1 (RTL1), а класс В - в RTTI2 (RTL2), то обращения RTL1.GetClass(В) и RTL2.GetClass(А) - хоть из штанов выпрыгни - гарантированно вернут nil.
MikProg (2006-07-12 10:00:00) [100]Что вы как дети, ей богу!
>с чего вообще решено, что не отрабатывает 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;