Board index » delphi » Q: DLL LoadLibrary/FreeLibrary (access violation)

Q: DLL LoadLibrary/FreeLibrary (access violation)

Hello to all DLL-using gurus...

My application dynamically loads TUTIL32.DLL with the
LoadLibrary API. It works then fine, and every
call to the DLL function succeed.

However, when the program terminates, it provoques
an access violation.

This problem does not occur if I do not call
FreeLibrary. It does not occur neither if I load the
DLL at startup (by declaring the externals functions).

The exception does not seem to come from code in
the forms.pas file, and of course I do not call
anymore the DLL after the FreeLibrary call.

If anyone has the slightest idea about how to
avoid the exception, I would be happy to hear
about his idea, as I have no clue on how to find it.

Notes :I think it's not good manners not to call
       FreeLibrary, so I wish to call it

       I use dynamic loading because the DLL functions
       are not normally used in the program, and I
       want it to run event if the DLL is missing
       (although the DLL functions will not be available,
        of course)

any suggestion welcome, thank you

Vincent Schmid

vsch...@polylog.ch

 

Re:Q: DLL LoadLibrary/FreeLibrary (access violation)


Vincent,
   You might be trying to unload a DLL which has already been freed from
memory. I have written numerous DLL's in which I free the library in the
FINALIZATION section , rather than leave that option to the programmer. Why
don't you check to see what the status of that DLL is AFTER your function
calls and PRIOR to making the FREELIBRARY call, just to make sure that there
is in fact a library to free?
                                      Good luck!!
-Dave
http://www.erols.com/dparsons
----------------------------------------------------
dpars...@erols.com
-----------------------------------------------------
Quote
Vincent Schmid wrote in message <366FF104.1403E...@polylog.ch>...
>Hello to all DLL-using gurus...

>My application dynamically loads TUTIL32.DLL with the
>LoadLibrary API. It works then fine, and every
>call to the DLL function succeed.

>However, when the program terminates, it provoques
>an access violation.

>This problem does not occur if I do not call
>FreeLibrary. It does not occur neither if I load the
>DLL at startup (by declaring the externals functions).

>The exception does not seem to come from code in
>the forms.pas file, and of course I do not call
>anymore the DLL after the FreeLibrary call.

>If anyone has the slightest idea about how to
>avoid the exception, I would be happy to hear
>about his idea, as I have no clue on how to find it.

>Notes :I think it's not good manners not to call
>       FreeLibrary, so I wish to call it

>       I use dynamic loading because the DLL functions
>       are not normally used in the program, and I
>       want it to run event if the DLL is missing
>       (although the DLL functions will not be available,
>        of course)

>any suggestion welcome, thank you

>Vincent Schmid

>vsch...@polylog.ch

Re:Q: DLL LoadLibrary/FreeLibrary (access violation)


Quote
Dave Parsons wrote:

> Vincent,
>    You might be trying to unload a DLL which has already been freed from
> memory. I have written numerous DLL's in which I free the library in the
> FINALIZATION section , rather than leave that option to the programmer. Why
> don't you check to see what the status of that DLL is AFTER your function
> calls and PRIOR to making the FREELIBRARY call, just to make sure that there
> is in fact a library to free?
>                                       Good luck!!
> -Dave

Why don't you post a specific example, Dave?  I'm quite interested in a
number of the ideas you are alluding to, but you only tantalize us.  :-)

{1}  How can a library free itself in its finalization-code?
{2}  What were you experiencing when you were "leaving that option to
the programmer," that prompted you to do it the other way?
{3}  How does one go about "checking the status of the DLL after your
function call," and are there any race-conditions possible here?
{4}  How does the program's behavior when using FreeLibrary, differ from
that done by default by Windows when the DLL is mentioned in an
"external" clause?

Whew!  :-)

Re:Q: DLL LoadLibrary/FreeLibrary (access violation)


: Vincent Schmid <vsch...@polylog.ch> wrote:

Quote
>My application dynamically loads TUTIL32.DLL with the
>LoadLibrary API. It works then fine, and every
>call to the DLL function succeed.

>However, when the program terminates, it provoques
>an access violation.

This is a known problem with no resolution.

--
Stefan Hoffmeister    (http://www.econos.de/)
No private email, please, unless expressly invited.

Re:Q: DLL LoadLibrary/FreeLibrary (access violation)


Quote
Vincent Schmid wrote:
>My application dynamically loads TUTIL32.DLL with
>the LoadLibrary API. It works then fine, and every
>call to the DLL function succeed.  When the program
>terminates it provoques an access violation. This
>problem does not occur if I do not call FreeLibrary.

You didn't indicate where in your app the DLL is loaded
and freed, but almost certainly you're freeing too early.

To stab in the dark I'd guess you're

(i) doing LoadLibrary in a form initialization section

(ii) using the library in either its FormCreate,
      FormShow or in one of its children

(iii) closing the function handles in either its
      FormDestroy, the OnDestroy of one of its
      components, controls or child forms,
      or the FormClose of an MDI child, and

(iv) then calling FreeLibrary in form finalization.

The above is a recipe for access violation because

- unless you explicitly free a form within your code
  (via Free method or MDI child caFree) its
  FormDestroy handler isn't called until *after*
  its unit's finalization - when the Forms unit
  finalization calls Application.DestroyComponents

- MDI children don't get FormClose until *after*
  their finalization if the application quit due to
  clicking system menu or calling MainForm.Close,
  Application.Terminate or PostQuitMessage.

That's my best guess.  The fix would be to load/free
the DLL in your main form's OnCreate & OnDestroy
methods and ensure that the DLL is not used in either
the DPR or any of the initialization/finalization sections
of your forms or their components.  Similarly be sure to
avoid use of AddExitProc in your forms or components
(it's obsolete anyway because it's not package-safe) .

The other nice way to use a DLL is to encapsulate it
in an object or component, loading/freeing in that
object's constructor/destructor.  Provided that access
is only via properties (ie handles aren't recklessly
passed out) this ensures that functions aren't called
beyond module lifetime.  As an example see the
TIBEventAlerter component in samples\ibctrls.pas
which encapsulates GDS32.DLL.

It's not always possible to encapsulate things nicely, but
too often people just LoadLibrary/GetProcAddress and
shove the pointers into global variables with little thought
for limiting their scope.  IME the majority of shutdown AVs
can be traced back to global variables.  Inevitably you
end up with flags all over the place to disable shutdown-
time activity everywhere that the variables might be used.
Several of the uglier VCL units bear that curse.  (Other
problems with global variables of course are threadsafety
and data segment limits.)

By the way, don't even think about loading/freeing the
DLL in your DPR before/after Application.Run: if you
get a runtime error your DLL won't get freed.

HTH

Grant Walker
sydney australia

Re:Q: DLL LoadLibrary/FreeLibrary (access violation)


: "Grant Walker" <g...@zzenternet.com.au.zznospam> wrote:

Quote
>To stab in the dark I'd guess you're

Grant, there is no need to stab around in the dark - it TUTIL32.DLL
that causes these problems.

There is nothing that can be done.

--
Stefan Hoffmeister    (http://www.econos.de/)
No private email, please, unless expressly invited.

Re:Q: DLL LoadLibrary/FreeLibrary (access violation)


Hello,

I wish to thank everybody who replied to my question,
Stefan, Grant, Dave and Meir (up to now)...

I made some more investigation and it appears that
the problem could be related to some specificity of
the TUTIL32.DLL (for those who don't know, this is
the DLL provided by Borland to rebuild or modify
tables in a database)

I can load it and unload it without problem,
as long as no database is active. If one
database is active, I get the access violation.

I have been misleaded by the fact that the problem
only happens with DYNAMICALLY loaded DLL.
Things remain unclear however, as I cannot find
any good combination for the order of Loading,
opening database, closing it and unloading the dll.

I have still to look more precisely what happens and
when, and I will post some code which illustrates the
problem as soon as can make it simple and clear.

Vincent

vsch...@polylog.ch

Other Threads