Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2005.07.18;
Скачать: [xml.tar.bz2];

Вниз

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 вся ветка

Форум: "WinAPI";
Текущий архив: 2005.07.18;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.61 MB
Время: 0.038 c
4-1116440529
Jetus
2005-05-18 22:22
2005.07.18
Как получить всю возможную инфу о сервисе в ХР?


1-1120335665
P.N.P.
2005-07-03 00:21
2005.07.18
Передача строки другой копии приложения


1-1120031733
Victor!
2005-06-29 11:55
2005.07.18
Вопрос про OLE container


1-1119788329
начинающий
2005-06-26 16:18
2005.07.18
Как определить, пуста ли определенная папка?


14-1119723874
Иксик
2005-06-25 22:24
2005.07.18
Как легче всего доехать из Москвы в Питер?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский