By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
464,747 Members | 1,308 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 464,747 IT Pros & Developers. It's quick & easy.

ctypes - unloading implicitly loaded dlls

P: n/a
(my apologies if this is a repost, but it sure seems like the first
attempt disappeared into the ether...)

I'm writing a program that uses functionality from two different sets of
cdlls which reside in two different directories, call them 'libA.dll'
and 'libB.dll'. Although I don't directly use it, both directories
contain a dll with the same name, although they aren't in fact
identical. Call them, "libC.dll". However, the c-functions I call from
the clls I do use seem to implicitly use "libC.dll". The problem that
occurs after I load one dll and call functions in it, when I try to load
the second dll I get windows errors because the second dll tries to call
a function in its version of libC.dll, but it finds the version meant
for libB.dll, which doesn't contain that function.

Oy, I hope some sample code makes it clearer:

def demo():

A = ctypes.cdll.LoadLibrary('/path1/libA.dll')
A.foo() # implicitly uses '/path1/libC.dll'

_ctypes.FreeLibrary(A._handle)

# CRASH!
B = ctypes.cdll.LoadLibrary('/path2/libB.dll')
# "The procedure entry point some_func could not be located
# in the dynamic link library libC.dll.":

# libB.dll wants to use code from '/path2/libC.dll', but
# instead it finds '/path1/libC.dll' already loaded
# in memory, which doesn't
# contain the function call it wants.
Assuming my understanding of things is correct, then I believe what I
need to do is to remove /path1/libC.dll from memory before I try loading
libB.dll, but I haven't found any way of doing that. Can anyone offer
my some suggestions? Or, am I S.O.L.?
Notes:
* the two sets of dlls are supplied by a vendor for working with its
COTS packages; I don't have any control over the dll names used or the
code therein.
* If I leave out the call to A.foo(), then I don't crash, but if I leave
out the FreeLibrary call as well then I do crash.
* I've tried manipulating the PATH before loading the dlls, to no effect.
* I've tried del'ing A and running gc.collect() before loading B.

Thanks,

Scott
Jul 28 '08 #1
Share this Question
Share on Google+
2 Replies

P: n/a
pigmartian <sc*******@comcast.netwrote:
I'm writing a program that uses functionality from two different sets of
cdlls which reside in two different directories, call them 'libA.dll'
and 'libB.dll'. Although I don't directly use it, both directories
contain a dll with the same name, although they aren't in fact
identical. Call them, "libC.dll". However, the c-functions I call from
the clls I do use seem to implicitly use "libC.dll". The problem that
occurs after I load one dll and call functions in it, when I try to load
the second dll I get windows errors because the second dll tries to call
a function in its version of libC.dll, but it finds the version meant
for libB.dll, which doesn't contain that function.

Oy, I hope some sample code makes it clearer:

def demo():

A = ctypes.cdll.LoadLibrary('/path1/libA.dll')
A.foo() # implicitly uses '/path1/libC.dll'

_ctypes.FreeLibrary(A._handle)

# CRASH!
B = ctypes.cdll.LoadLibrary('/path2/libB.dll')
# "The procedure entry point some_func could not be located
# in the dynamic link library libC.dll.":

# libB.dll wants to use code from '/path2/libC.dll', but
# instead it finds '/path1/libC.dll' already loaded
# in memory, which doesn't
# contain the function call it wants.
Assuming my understanding of things is correct, then I believe what I
need to do is to remove /path1/libC.dll from memory before I try loading
libB.dll, but I haven't found any way of doing that. Can anyone offer
my some suggestions? Or, am I S.O.L.?
You could try loading C explicitly with ctypes.LoadLibrary() before
loading A, then you'll have a handle to unload it before you load B.

I think I'd probably split the code into two or three processes
though. Perhaps use http://pypi.python.org/pypi/processing to
communicate between them. That should get you out of DLL Hell!
(Don't load any of the DLLs before you start the worker processes
off.)

--
Nick Craig-Wood <ni**@craig-wood.com-- http://www.craig-wood.com/nick
Jul 28 '08 #2

P: n/a
Nick Craig-Wood wrote:
You could try loading C explicitly with ctypes.LoadLibrary() before
loading A, then you'll have a handle to unload it before you load B.
I did think of that, but no luck. Guess the cdll doesn't look for a dll
loaded already by python. I guess that does make sense.

I think I'd probably split the code into two or three processes
though. Perhaps use http://pypi.python.org/pypi/processing to
communicate between them. That should get you out of DLL Hell!
(Don't load any of the DLLs before you start the worker processes
off.)
That was quite a helpful suggestion, thank you. I had been using the
subprocess module actually, but really didn't like that approach.
processing is much nicer. Pipes, in particular, is quite handy.

~Scott

Jul 29 '08 #3

This discussion thread is closed

Replies have been disabled for this discussion.