Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

finalization code in DLL's

482 views
Skip to first unread message

Mats Gefvert

unread,
Oct 19, 2005, 10:53:25 AM10/19/05
to
I have a question regarding initialization and finalization code in
DLL's. I've noticed the question has come up before but I haven't seen
any good answer for it (yet).

We have a few DLL's which we use in our projects. They've worked great
so far, but since upgrading to ZeosDBO-6.1.5 we've noticed errors. The
problem is that we load a DLL, which in turn uses ZeosDBO to load
libmysql.dll. The problem is that the libmysql-unload code is in a
finalization section of a specific file; and when we've traced the
execution, we see that the finalization code isn't run when we unload
the DLL though FreeLibrary(), it only runs as the program exits.

Which undoubtedly leads to problems. In this case, the DLL is unloaded,
and libmysql.dll unloads along with it, and a couple of seconds later
when the big application shuts down, the finalization code is run and
which now points into unreferenced memory, and smack! there goes an
EAccessViolation.

Packages seem better. When examining the core files, we've seen that
packages have functions like LoadPackage and UnloadPackage that handles
cleanup (initialization and finalization code) correctly. The main
difference seems to be that BPL files export two functions called
"Initialize" and "Finalize", which handles all of these finalization
blocks, while DLL files don't.

While we certainly *can* rewrite our DLL's to work as packages instead,
it isn't really the way we were hoping to go. Is there any way to go
around this problem, or make Delphi add these functions manually to DLL's?

Sincerely
Mats Gefvert

P.S. Still using Delphi 5. Should have upgraded but we ran out of time.

Mike Williams (TeamB)

unread,
Oct 19, 2005, 10:58:36 AM10/19/05
to
Mats Gefvert wrote:

> The problem is that the libmysql-unload code is in a finalization
> section of a specific file; and when we've traced the execution, we
> see that the finalization code isn't run when we unload the DLL
> though FreeLibrary(), it only runs as the program exits.

That's simply the way finalization code works: it runs when the program
ends. Is your DLL manually loading the DB dll using LoadLibrary or is
it implicitly loaded via external?

--
-Mike (TeamB)

Mats Gefvert

unread,
Oct 20, 2005, 3:19:08 AM10/20/05
to

So finalization code in a DLL automatically hooks onto the process exit
code? It does come across as a little strange, since whenever
FreeLibrary is called, all those pointers must become void, right?
Finalization statements effectively kills dynamically loaded DLL's, in
that case?

Everything in our program happens pretty much dynamically through
LoadLibrary/FreeLibrary. Both when we load "our" DLL and when that DLL,
in turn (through ZeosDBO) loads libmysql.dll.

But I'm sure BPL is the way to go in this case.

/ Mats

Mats Gefvert

unread,
Oct 20, 2005, 3:14:04 AM10/20/05
to Mike Williams (TeamB)
Mike Williams (TeamB) wrote:

No, everything happens dynamically through LoadLibrary/FreeLibrary; both
when we load "our" DLL and when our DLL in turn (through ZeosDBO) loads
libmysql.dll.

It starts looking like a design error, then.

But we'll probably go through BPL's instead.

/ Mats

Mats Gefvert

unread,
Oct 20, 2005, 3:31:34 AM10/20/05
to
Mats Gefvert wrote:
> No, everything happens dynamically through LoadLibrary/FreeLibrary; both
> when we load "our" DLL and when our DLL in turn (through ZeosDBO) loads
> libmysql.dll.
>
> It starts looking like a design error, then.
>
> But we'll probably go through BPL's instead.

Okay, that was posted twice. I'm really starting to dislike Thunderbird.

/ Mats

krisztian pinter

unread,
Oct 20, 2005, 3:42:18 AM10/20/05
to
On Thu, 20 Oct 2005 09:31:34 +0200, Mats Gefvert <finke...@home.se>
wrote:

> Okay, that was posted twice. I'm really starting to dislike Thunderbird.

avoid Opera's "Revolutionary" Mail and News Client too.

Mats Gefvert

unread,
Oct 20, 2005, 6:16:44 AM10/20/05
to
> But I'm sure BPL is the way to go in this case.

Nope.

Ran into some pretty ugly problems with that. Aside from the fact that
the size of our dll's jumped from 2 to 7 megabytes when we made bpl's
instead.

Dang it... this is not funny.

Is there *any* way that finalization code can be accessed in DLL's
manually? Faking calls to the entry point? Manually looping through
ExitCode handlers and comparing pointers to see if the fall within the
DLL memory segment?

/ Matt

Mats Gefvert

unread,
Oct 21, 2005, 3:40:32 AM10/21/05
to
>> But I'm sure BPL is the way to go in this case.
>
> Nope.

Just to recap:

We solved the problem using regular DLL's. All that was required was a
different mindset:

When a Delphi program dynamically loads a library with finalization code
in it, the two fuse together to the point where it's physically
impossible to separate them. So we don't. We treat the library as if it
was automatically loaded by Windows on program startup, and we never
unload it. Upon exit, the DLL is still in memory, all finalization code
is run, and Windows cleans up everything the way Windows would have anyway.

Case closed.

/ Mats

0 new messages