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

Вниз

Что может быть причиной невыгрузки библиотеки?   Найти похожие ветки 

 
Aleksandr.   (2005-06-06 15:48) [0]

В программе динамически грузится библиотека, юзающая FireBird, при завершении работы программы, соответственно, вызывается FreeLibrary. Но в случае какой-либо ошибки в библиотеке, даже обработанной try..except, на FreeLibrary программа просто зависает. Что может вызывать такой вис и есть ли способ выгрузить библиотеку гарантированно?


 
Digitman ©   (2005-06-06 15:50) [1]


> Что может вызывать такой вис


все что угодно


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


нет


 
Aleksandr.   (2005-06-06 15:56) [2]

Digitman:
> Все что угодно

Ну например? Exception"ы обрабатываются нормально, чего ей для жизни может не хватать?


 
Digitman ©   (2005-06-06 16:01) [3]


> Exception"ы обрабатываются нормально


не факт


> чего ей для жизни может не хватать?


об этом можно говорить как минимум имея перед носом код деинициализации модуля


 
sniknik ©   (2005-06-06 16:06) [4]

а код в которой "нормально" обрабатывается Exception? по моему тоже нужен. ;)


 
Anatoly Podgoretsky ©   (2005-06-06 16:29) [5]

А как быть с такими случаями в библиотеке, как

try
  ...
except
end;


 
Aleksandr.   (2005-06-06 16:32) [6]

Хорошо. Код, который работает с библиотекой:

procedure AddLog(S : shortstring);
var
 t : string;
begin
 writeln(GetOemStr(s));
 with TFileStream.Create("LOG\atidb.log",fmOpenReadWrite OR fmShareDenyNone) do try
   Seek(0,soEnd);
   t:=FormatDateTime("dd.mm.yyyy hh:nn:ss",Now)+":"+#9+s+#13#10;
   Write(t[1],length(t))
 finally
   Free
 end
end;

procedure InitDBSettings;
var
 P, C : PChar;
begin
 hm_SQLModule:=LoadLibrary("atidb.dll");
 if hm_SQLModule<>0 then try
   @vInitDBSettings:=GetProcAddress(hm_SQLModule,"InitDBSettings");
   @vDBInitProcs:=GetProcAddress(hm_SQLModule,"InitProcs");
   @vFreeDB:=GetProcAddress(hm_SQLModule,"FreeDB");
   vDBInitProcs(@AddLog);
   P:=StrNew(PChar(GetCurrentDir));
   C:=StrNew(PChar(CheckDir(GetCurrentDir)+"Bases\bases.fdb"));
   vInitDBSettings(C,P);
   @vInitBaseTables:=GetProcAddress(hm_SQLModule,"InitBaseTables");
   vInitBaseTables;
   vFreeDB
 finally
   FreeLibrary(hm_SQLModule)
 end
end;


вот код функций в Dll:

function InitDBSettings(szDataBaseName : PChar; const szMainDir : PChar=nil;
        const szDataBaseParams : PChar=nil) : integer; stdcall;
begin
 if FATI<>nil then
   FreeAndNil(FATI);
 FATI:=TATIDB.Create(StrPas(szMainDir), StrPas(szDataBaseName), strPas(szDataBaseParams));
 Result:=FATI.Status
end;

function FreeDB() : longbool; stdcall;
begin
 try
   if FATI<>nil then
     FreeAndNil(FATI);
   Result:=true
 except
   Result:=false
 end
end;

function InitProcs(LogPtr : Pointer; const ProgressPtr : Pointer=nil; const MessagePtr : Pointer=nil) : longbool; stdcall;
begin
 try
   vDBDllLog:=LogPtr;
   vDBDllProgress:=ProgressPtr;
   vDBDllShowMsgProc:=MessagePtr;
   Result:=true
 except
   Result:=false
 end
end;

function InitBaseTables : integer; stdcall;
begin
 if FATI=nil then
   Result:=0
 else begin
   FATI.InitBaseTables;
   Result:=FATI.Status
 end  
end;


Вот объявления:

var
 vDBDllLog : procedure (Msg : shortstring);

 vInitDBSettings   : function(szDataBaseName : PChar; const szMainDir : PChar=nil;
                              const szDataBaseParams : PChar=nil) : integer; stdcall;
 vInitBaseTables   : function : integer; stdcall;
 vFreeDB           : function : longbool; stdcall;
 vDBInitProcs      : function(LogPtr : Pointer; const ProgressPtr : Pointer=nil;
                              const MessagePtr : Pointer=nil) : longbool; stdcall;


Вот ключевые для вопроса методы FATI -

constructor TATIDB.Create(aMainDir, aDBName: TFileName; aDBParams: string);
begin
 Inherited Create;
 AddLog("Initialization...");
 try
   FStatus:=0;
   FActive:=false;
   FDBName:=aDBName;
   FMainDir:=CheckDir(aMainDir);
   if FMainDir="" then
     FMainDir:=CheckDir(GetCurrentDir);
   FBasesDir:=FMainDir+"BASES\";
   FOutDir:=FMainDir+"OUT\";
   FDB:=TIbDataBase.Create(nil);
   FDB.DatabaseName:=aDBName;
   FDB.Params.Text:=aDBParams;
   if aDBParams="" then
     FDB.Params.Add("lc_ctype=WIN1251");
   FDB.LoginPrompt:=false;
   FIT:=TIbTransaction.Create(nil);
   FIT.DefaultAction:=TACommitRetaining;
   FIT.Params.Text:="read_committed"#13#10"rec_version"#13#10"nowait";
   FIT.DefaultDataBase:=FDB;
   FDB.DefaultTransaction:=FIT;
   DoLog("OK")
 except
   on E:Exception do
     DoLog(E.Message)
 end
end;

procedure TATIDB.InitBaseTables;
var
 bWasConnect : boolean;
 s           : string;
 P           : PChar;
 i           : integer;
 L           : TStrings;
 Q           : TIbQuery;
begin
 AddLog("Init modules...");
 {$Region "Инициализация библиотеки запросов"}
 hm_SQLModule:=LoadLibrary(PChar(SQLModuleName));
 if hm_SQLModule<>0 then begin
   DoLog("OK");
   AddLog("Init procedures...");
   @vBaseCreateSQL:=GetProcAddress(hm_SQLModule,"BaseCreateSQL");
   @vCreateSQL:=GetProcAddress(hm_SQLModule,"CreateSQL");
   @vGetSQL:=GetProcAddress(hm_SQLModule,"GetSQL");
   @vGetUserTablesIDS:=GetProcAddress(hm_SQLModule,"GetUserTablesIDs");
   if (@vBaseCreateSQL<>nil) AND (@vCreateSQL<>nil) AND (@vGetSQL<>nil) then
     DoLog("OK")
   else if @vBaseCreateSQL=nil then
     DoLog("function BaseCreateSQL not found!")
   else if @vCreateSQL=nil then
     DoLog("function CreateSQL not found!")
   else if @vGetUserTablesIds=nil then
     DoLog("function GetUserTablesIds not found!")
   else if @vGetSQL=nil then
     DoLog("function GetSQL not found!")
 end
 else begin
   DoLog(Format("library %s not found!",[SQLModuleName]));
   Exit
 end; {$EndRegion}
 AddLog("Init DB connection...");
 bWasConnect:=FDB.Connected;
 if NOT bWasConnect then
   FDB.Connected:=true;
 DoLog("OK");
 try
   AddLog("Init userinfo...");
   {$Region "проверка на наличие и создание UserCard"} try
     FillChar(FUserCard,SizeOf(FUserCard),0);
     FUserCard.ID:=NewMinRegister;
     if NOT TableExists("userinfo") then begin
       if @vBaseCreateSQL<>nil then begin
         i:=vBaseCreateSQL(bs_CreateUserInfo);
         GetMem(P,i);
         try
           vBaseCreateSQL(bs_CreateUserInfo,P);
           s:=StrPas(P)
         finally
           FreeMem(P)
         end;
         Q:=TIbQuery.Create(nil);
         with Q do try
           DataBase:=FDB;
           L:=TStringList.Create;
           try
             L.Text:=s;
             while L.Count>0 do begin
               s:=L.Strings[0];
               L.Delete(0);
               if s<>"" then begin
                 SQL.Text:=s;

                Собственно, вот тут, если воткнуть ошибочную строку запроса, произойдет выход в следующий except

                 ExecSQL;                  
                 FIT.CommitRetaining
               end
             end
           finally
             L.Free
           end        
        finally
           Q.Free
         end;
         DoLog("Recreated");
       end
       else
         DoLog("Cannot init vBaseCreateSQL")
     end
     else
       DoLog("OK");
   except
     on E:Exception do
       DoLog(E.Message)      // вот этот эксепт обрабатывает ошибку, но выгрузки библиотеки больше не произойдет
   end; {$EndRegion}
 finally
   FDB.Connected:=bWasConnect
 end
end;

destructor TATIDB.Destroy;
begin
 AddLog("Finalization...");
 try
   if FIT.InTransaction then
     FIT.CheckAutoStop;
   if FIT.Active then
     FIT.Active:=false;
   FreeAndNil(FIT);
   if FDB.Connected then
     FDB.Connected:=false;
   FreeAndNil(FDB);
   if hm_SQLModule<>0 then
     FreeLibrary(hm_SQLModule);
   DoLog("OK")
 except
   on E:Exception do
     DoLog(E.Message)
 end;
 inherited
end;

procedure TATIDB.AddLog(Msg: shortstring);
begin
 FLogS:=Msg
end;

procedure TATIDB.DoLog(Msg: shortstring);
begin
 FLogS:=FLogS+Msg;
 if Assigned(VDBDllLog) then try
   vDBDllLog(FLogS)
 except
 end;
 FLogS:=""
end;



 
Aleksandr.   (2005-06-06 16:35) [7]

В итоге лог работы будет выглядеть вот так:

06.06.2005 16:18:41: Initialization...OK
06.06.2005 16:18:41: Init modules...OK
06.06.2005 16:18:41: Init procedures...OK
06.06.2005 16:18:41: Init DB connection...OK
06.06.2005 16:18:46: Init userinfo...unsuccessful metadata update
Unknown columns in index USERINFO_IDX1
06.06.2005 16:18:46: Finalization...OK


 
sniknik ©   (2005-06-06 17:02) [8]

может "пальцем в небо"... но, модуль ShareMem используется?


 
Aleksandr.   (2005-06-06 17:39) [9]

неа. В параметрах string не используется.


 
sniknik ©   (2005-06-06 17:49) [10]

а ты попробуй поставь, может забыл чего
...even those that are nested in records and classes...



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

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

Наверх




Память: 0.51 MB
Время: 0.034 c
4-1114683614
psa247
2005-04-28 14:20
2005.06.29
Корзина Windows


4-1115541375
psa247
2005-05-08 12:36
2005.06.29
RegOpenKey


4-1114577998
bobah
2005-04-27 08:59
2005.06.29
Невидимый курсор мыши


1-1117777385
msgipss
2005-06-03 09:43
2005.06.29
Как обработать исключение сгенерированное в чужом объекте


4-1115532157
Неуловимый Джо
2005-05-08 10:02
2005.06.29
имя exe-файла сервиса