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

Вниз

FreeLibrary   Найти похожие ветки 

 
kblc ©   (2005-05-26 07:13) [0]

Уважаемые мастера, почему такая фигня происходит???

if p.Loaded then
begin
  p.UpLoad;
  if not p.UpLoaded then
  Server[LOG_SERVER].ExecFunction("LOG "+format(""%s": невозможно выгрузить библиотеку (%s)",[Name,Copy(p.FileName,LastDelimiter("\",p.FileName)+1,length(p.FileName))]));
end;
p.Destroy;
....
end;

вот функция p.UpLoad:
procedure TLibrary.UpLoad;
begin
 if Loaded then
 begin
   if Assigned(ExecFunction) then ExecFunction("STOP");
   prUpLoaded:=FreeLibrary(LibHandle);
 end else prUploaded:=true;
end;


функция выполняеться замечательно prUploaded = TRUE, но, как только переходим на след. строку
if not p.UpLoaded then
то p как такавое "Inaccesible Type"
Почему так получаеться?


 
kblc ©   (2005-05-26 07:16) [1]

забыл написать: ExecFunction("STOP"); выполняеться в самой библиотеке, хэндл которой LibHandle.
вот на что она ссылаеться:


function LibExecProcedure(const Param: string): string;
begin
 Result:="";
 if Param = "START" then
 begin
   if not Assigned(fmMain) then
   begin
     fmMain:=tfmMain.Create(nil);
   end;
   fmMain.ShowModal;
 end else
 if Param = "STOP" then
 begin
   LibraryServer:=nil;
   SelfInfo:=nil;
   fmMain:=nil;
 end;
end;


 
Digitman ©   (2005-05-26 09:02) [2]


> "Inaccesible Type"


это - сообщение дебагера, говорит оно о том, что просмотреть содержимое переменной p в дан.момент не представляется возможным по причине особенностей работы опимизатора, временно разместившего в дан.момент значение p в одном из РОН


 
kblc ©   (2005-05-26 09:38) [3]

понятно... но, дальше, при p.Destroy вызываеться получаеться так:

destructor TLibtary.Destroy;
begin
 ......
 inherited;         <<---
end;


после выполнения этой строчки возникает окно access violation и открываеться окно дебуггера, в котором кроме "?" ничего нет! почему?


 
Digitman ©   (2005-05-26 09:45) [4]


> почему?


ну наверно потому что объект уже не существует


 
kblc ©   (2005-05-26 10:11) [5]

В каких случаях он может "уже не существовать"????

ведь я его только начал уничтожать???

и вот ещё: проблема..
 if Assigned(ProgressLabel) then
    ProgressLabel.Caption:=format(""%s":"#13"сохранение переменных в реестре (%d)...",[prName,CONST_COUNT]);

при выполении ф-ии format опять возникает access violation. Почему?

я так понимаю, что я где-то динамически забиваю память. Могу ли я её где-либо "затирать" ??? и как такое возможно?

у меня всё создаёться class"ами... т.е. "затирание" не должно происходить?

так же у меня при работу с библиотеками не передаёться ничего кроме class"ов ... и integer"ов..

что я делаю не так?


 
alpet ©   (2005-05-26 10:16) [6]

Была здесь где-то похожая проблема, все заработало когда из деструктора убрали inherited.


 
Digitman ©   (2005-05-26 10:31) [7]


> kblc ©   (26.05.05 10:11) [5]
> ведь я его только начал уничтожать???


не-а... ты просто вызвал некий метод под названием Destroy ... а он - виртуальный ...


 
kblc ©   (2005-05-26 11:40) [8]

2 aplet:
 проблема в том, что я ещё не вызвал метод destroy я просто сделал FreeLybrary(), и именно после этого происходит что-то нехорошее... :(


 
kblc ©   (2005-05-26 11:41) [9]

я полностью убрал FreeLibrary и сразу после этого всё остальное заработало(!!!!!!) fuck! из-за чего?


 
Digitman ©   (2005-05-26 11:51) [10]


> полностью убрал FreeLibrary и сразу после этого всё остальное
> заработало


что у тебя творится в dll ?


 
kblc ©   (2005-05-26 11:53) [11]

2 Digitman:

у меня в библиотеке подключен Forms и вызываеться Application.CreateForm() при окончании работы я вызываю Application.Terminate;
+ При инициализации библиотеки вызываеться функция, которой передаёться TLibrary, я выделяю переменную, которой присваиваю этот класс.
Может ли быть так, что при Application.Terminate уничтожаеться эта переменная? т.е. вызываеться её метод Destroy (Free)? или она вся затираетьсяс в памяти??? хотя данный объект класс TLibrary был создан в exe файле.

Может ли быть такое


 
kblc ©   (2005-05-26 11:56) [12]

2 DigitMan

if Assigned(ProgressLabel) then
   ProgressLabel.Caption:=format(""%s":"#13"сохранение переменных в реестре (%d)...",[prName,CONST_COUNT]);

но при вот этом проблема не исчезла

постю кода библиотеки:


function LibExecProcedure(const Param: string): string;
begin
 Result:="";
 if Param = "START" then
 begin
   if not Assigned(fmMain) then
   begin
     Application.CreateForm(TfmMain, fmMain);
 end;
   fmMain.ShowModal;
 end else
 if Param = "STOP" then
 begin
   Application.Terminate;
 end;
end;

procedure LibDispProcedure(var MSG: TMessage);
begin
 if (Msg.Msg>WM_USER) and (Msg.Msg<=MSG_COUNT) and Assigned(fmMain) then
    fmMain.Dispatch(Msg);
end;

procedure LibInfoProcedure(const Lib: TLibrary; const LibServer: TServer); stdcall;
begin
 SelfInfo :=         Lib;
 Lib.LibName:=       "FIRST_FANTOM_LOADER";
 Lib.LibCaption :=   "Загрузчик "Фантом"";
 Lib.LibClass :=     lcLoader;
 Lib.ExecFunction := LibExecProcedure;
 Lib.DispatchMsg :=  LibDispProcedure;
 LibraryServer :=    LibServer;

 Lib.LibFuncs.Add("START");
 Lib.LibFuncs.Add("STOP");

 Application.Initialize;
end;

exports
 LibInfoProcedure name TLibInfoProcedureName;

begin
end.


 
Digitman ©   (2005-05-26 12:09) [13]


> procedure LibInfoProcedure(const Lib: TLibrary; const LibServer:
> TServer); stdcall;
> begin
> ...
>  Application.Initialize; //это что еще за байда ?!
> end;


где sharemem ?


 
Anatoly Podgoretsky ©   (2005-05-26 12:12) [14]

Да тут наверно еще и классы используются.


 
Digitman ©   (2005-05-26 12:15) [15]


> Anatoly Podgoretsky ©   (26.05.05 12:12) [14]
> Да тут наверно еще и классы используются.


тут, судя по всему, - каша ... завареная на ОБС ..


 
kblc ©   (2005-05-26 12:21) [16]

что за ОБС ????

да, классы используються...
причём ТОЛЬКО КЛАССЫ...

sharemem нужно куда добавлять? и нужно ли его добавлять? если я не ошибаюсь, то в каждый юнит, причём первым. так?


 
Digitman ©   (2005-05-26 12:32) [17]


> что за ОБС ????


Одна Баба Сказала


 
kblc ©   (2005-05-26 12:37) [18]

2 DigitMan:
ты обвиняешь меня в неграмотности написания?
я пишу исходя из определённых требований и личных соображений одновременно.

Лучше бы дал какой-нибудь дельный совет.
что сделать конкретно?


 
Digitman ©   (2005-05-26 12:42) [19]


> личных соображений


угу .. давай про "личные" ..

те или иные обращения к объекту Application в теле dll-кода прокомментируй ?


 
kblc ©   (2005-05-26 12:45) [20]

ок:

Application.Initialize - нафиг не нужен (просто эксперементировал),

Application.CreateForm()  - для создания формы. почему я не сделал fmMain:=tfmMain.create ??? потому что(!!!!) потом буду использоваться mdi формы, которым нужно что бы было определено application.mainform.

application.terminate (проверено, что после вызова это фени библиотека сама выгружаеться)

что-нибудь ещё?


 
Digitman ©   (2005-05-26 12:53) [21]


> Application.Initialize - нафиг не нужен (просто эксперементировал),
>


ну где-то ж ты это видел ?) ... из ОБС, очевидно ..


> Application.CreateForm()  - для создания формы. почему я
> не сделал fmMain:=tfmMain.create ??? потому что(!!!!) потом
> буду использоваться mdi формы, которым нужно что бы было
> определено application.mainform


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


> application.terminate (проверено, что после вызова это фени
> библиотека сама выгружаеться)


с какого перепугу-то ?! ты же ЯВНО выгружаешь быбл-ку в своем UpLoad ?!


 
Игорь Шевченко ©   (2005-05-26 12:55) [22]


> application.terminate (проверено, что после вызова это фени
> библиотека сама выгружаеться)


Не выгружается.


 
kblc ©   (2005-05-26 12:59) [23]

я не хочу спорить!
неужели вам так сложно показать мне КАК сделать правильно????
я уже запарился ...
что мне нужно сделать?


 
Eraser ©   (2005-05-26 13:07) [24]

kblc ©   (26.05.05 09:38) [3]

понятно... но, дальше, при p.Destroy вызываеться получаеться так:

destructor TLibtary.Destroy;
begin
......
inherited;         <<---
end;


Сразу что бросилось в глаза, поменяй местами
......
и
inherited;


 
kblc ©   (2005-05-26 13:11) [25]

такой вопрос:
 как мне правильно инициализировать и работать внутри библиотеки... ?
 ведь мне нужно создать MDIFrom, а потом уже MDIChild"s формы (они тоже буду грузитьсяс из библиотек)...

 Будьте добры - подскажите как мне это сделать.


 
Digitman ©   (2005-05-26 13:13) [26]


> я не хочу спорить


ты не спорь, ты просто ДУМАЙ ВСЛУХ ...


 
Eraser ©   (2005-05-26 13:15) [27]

kblc ©   (26.05.05 13:11) [25] как мне правильно инициализировать и работать внутри библиотеки... ?

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


 
kblc ©   (2005-05-26 13:19) [28]

Объясните для чего нужен юнит ShareMem?


 
kblc ©   (2005-05-26 13:28) [29]

Добавил во все юниты (первым) ShareMem и
только что убрал при вызове TLibrary.Destroy функцию FreeLIbrary, теперь вообще всё заработало.. я НИЧЕГО НЕ ПОНИМАЮ!

Если оставить FreeLibrary то сразу после неё возникает ошибка
уже на строчке
Server[LOG_SERVER].ExecFunction("LOG "+format(""%s": выгрузка завершена.",[Name]));
причём, все параметры и сама ф-ия определены.


 
Digitman ©   (2005-05-26 13:28) [30]


> для чего нужен юнит ShareMem


единый менеджер памяти для всех потенциальных модулей делфи-приложения

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


 
Eraser ©   (2005-05-26 13:28) [31]

kblc ©   (26.05.05 13:19) [28]

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

ЗЫ Ставь его в самом начале uses.


 
Digitman ©   (2005-05-26 13:31) [32]


> Добавил во все юниты (первым) ShareMem


НЕЛЬЗЯ этого делать !

ShareMem, если необходимо, следует добавлять первым элементом в uses проекта
(т.е. текста взк-файла), а не в uses модулей в его составе !


 
kblc ©   (2005-05-26 13:52) [33]

Нашёл у себя проблемку...
при отсылке сообщения библиотеки... не хватало одной проверки.

но... я последовал вашим советам... теперь у меня получаеться вообще неописуемые прекрасы:

procedure TMainServer.InsideSendMsg(var Msg: TMessage);
var
 CanClose: boolean;
begin
 DispatchMsg(Msg);
 if Msg.Msg = SM_TERMINATE then
 begin
   if Assigned(CloseAction) then CloseAction(nil, CanClose);
 end;
end;

сюда приходит сообщение от dll-ки при уничтожении формы SM_TERMINATE ...
CloseAction = MyForm.CloseQuery
Он закрывает форму.. прекрасно выгружает библиотеку... но потом......

со стороны моей формы, создаёться таймер, который подождёт 2 сек. и сам закроет форму.

но проблема не в этом...

когда я дебугю procedure TMainServer.InsideSendMsg(var Msg: TMessage) и когда курсор находиться на последнем end; после нажатия F8 вылетает debugger с "?" ... и надписью Threan #..  из-за чего? что-то я не понимаю...


 
Digitman ©   (2005-05-26 14:01) [34]

каша какая-то ...

"Смешались в кучу кони, люди.." (с) ..

и сообщения тут, и AV, и Inaccessible, и Application .. и чего только нет в солянке) ...

ты уж сосредоточься на чем-то конкретном ...


 
Digitman ©   (2005-05-26 14:03) [35]


> kblc ©   (26.05.05 13:52) [33]


ты знаком с трассировкой кода dll-проекта ?


 
Anatoly Podgoretsky ©   (2005-05-26 14:03) [36]

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


 
kblc ©   (2005-05-26 14:06) [37]

Вот сейчас проблема вот в этом:
суда приходит сообщение SM_TERMINATE

procedure TMainServer.InsideSendMsg(var Msg: TMessage);
var
 CanClose: boolean;
begin
 DispatchMsg(Msg);
 if Msg.Msg = SM_TERMINATE then
 begin
   CanClose:=true;
   if Assigned(CloseAction) then CloseAction(nil, CanClose);
 end;
end;


вот что вызывается на метод CloseAction:

procedure TfmMainServer.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
 CanClose:=Self.CanCloseFirst;
 if not Self.CanCloseSecond then
 begin
   if not Visible then Visible:=true;
   MainServer.Save;
   tim_Saving.Interval:=CNST_TIMER_SAVE_INTERVAL; //2*1000
   tim_Saving.Enabled:=true;
 end;
end;


А вот это выполняеться по таймеру:


procedure TfmMainServer.tim_SavingTimer(Sender: TObject);
begin
 tim_Saving.Enabled:=false;
 CanCloseFirst:=true;
 Close;
end;


когда я дебугю procedure TMainServer.InsideSendMsg(var Msg: TMessage) и когда курсор находиться на последнем end; после нажатия F8 вылетает debugger с "?" ... и надписью Thread #..  из-за чего? что-то я не понимаю...


 
kblc ©   (2005-05-26 14:08) [38]

2 DigitMan:
Конечно знаком! а как по-твоему я их отлаживаю???


 
Digitman ©   (2005-05-26 14:09) [39]


> из-за чего?


да из-за чего угодно.
шматок кода он и есть шматок кода.
в отрыве от остального кода рассуждать о причинах не имеет смысла.


 
kblc ©   (2005-05-26 14:09) [40]

извиняюсь за ляп:

procedure TfmMainServer.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
CanClose:=Self.CanCloseFirst;
if not Self.CanCloseFirst then
begin
  if not Visible then Visible:=true;
  MainServer.Save;
  tim_Saving.Interval:=CNST_TIMER_SAVE_INTERVAL; //2*1000
  tim_Saving.Enabled:=true;
end;
end;


 
Digitman ©   (2005-05-26 14:10) [41]


> kblc ©   (26.05.05 14:08) [38]


а шут его знает, КАК ты "их" отлаживаешь)

вообще-то еще клавиша F7 есть ... и asm-код ...


 
kblc ©   (2005-05-26 14:11) [42]

2 DigitMan:

запостить весь код??? 58 КБ текста (всё вместе)???


 
kblc ©   (2005-05-26 14:12) [43]

блин... я и на F7 жал! ... да ёпрст... а что за асм код - да-не знаю.... если это именено то окно дебуггера где одни знаки "?" ???


 
Digitman ©   (2005-05-26 14:12) [44]


> if not Self.CanCloseFirst then


в данном контексте выделенное жирным выдает дилетанта)
это тоже не ОБС ?


 
kblc ©   (2005-05-26 14:14) [45]

раньше там просто было CanClose - заменить не успел
DigitMan, отгадай откуда этот брался CanClose ???
наверное из объекта класса!


 
Digitman ©   (2005-05-26 14:17) [46]


> если это именено то окно дебуггера


что такое "окно дебуггера" ?

в этом окне - куча фреймов : фрейм секции кода, фрейм секции данных, фрейм секции стека, фрейм регистров CPU ...

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


 
kblc ©   (2005-05-26 14:23) [47]

2 Digitman: да, именно! я про это самое окно!...

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


 
Digitman ©   (2005-05-26 14:24) [48]

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


 
kblc ©   (2005-05-26 14:30) [49]

Digitman, что значит "проверить соглашения в вызове"?


 
Digitman ©   (2005-05-26 14:32) [50]

это значит что декларация п/п в вызывающем коде должна в точности соответствовать декларации той же п/п в вызываемом коде


 
kblc ©   (2005-05-26 14:41) [51]

2 Digitman: проверил все декларации.
Всё полностью совпадает.
Что ещё я могу сделать?


 
Digitman ©   (2005-05-26 14:44) [52]

например, привести сюда декларацию и реализацию метода DispatchMsg..


 
kblc ©   (2005-05-26 14:44) [53]

когда появляеться вот такая ошибка? EInOutError with message "I/O Error 103"


 
Digitman ©   (2005-05-26 14:45) [54]


> kblc ©   (26.05.05 14:44) [53]


как минимум - при файловом вводе/выводе ..


 
kblc ©   (2005-05-26 14:55) [55]

я нашёл в чём ошибка...

я постоянно вызываю метод DispatchMsg не используя SendMessage().. это естественно, ведь у меня классы не имеют хэндла...

тут я сам наступил на грабли... у меня вызывался метод MainServer.Save который выгружал все dll, но(!!!) изучая я пришёл к выводу, что функция ExecProcedure в библиотеке не успевает завершить свою работу (т.к. клсвенно вызвала метод MainSercver.Save, который уже выгрузил её саму).

Как же мне тогда сделать так, что бы этого не повторялось?

Я засунул метод Save в таймер ... который срабатывает после 2 секунд после обработки сообщения метода DispatchMsg. Тепрь всё работает. Никаких ошибок.
Но я считаю что это неправильно.

Как же мне сделать "правильно"?


 
Digitman ©   (2005-05-26 15:03) [56]


> функция ExecProcedure в библиотеке не успевает завершить
> свою работу


т.е. она реализует асинхронную логику ?... какого ж ... ты сразу об этом не упомянул ?)

ЧТО является признаком фактического (успешного или неуспешного) завершения работы алгоритма, инициированного к выполнению вызовом ExecProcedure() ?


 
kblc ©   (2005-05-26 15:12) [57]

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



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

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

Наверх




Память: 0.63 MB
Время: 0.041 c
1-1119671688
Starcom
2005-06-25 07:54
2005.07.18
ProgressBar как к нему привязать выполнение ... процесса?


9-1113114738
Mr.kokkls
2005-04-10 10:32
2005.07.18
Пересечение линии и прямоугольника


14-1119416444
тихий вовочка
2005-06-22 09:00
2005.07.18
Поступление в ВУЗ


1-1119835385
NeoPlayer
2005-06-27 05:23
2005.07.18
Работа со временем


14-1119409315
kaif
2005-06-22 07:01
2005.07.18
СПАМ