ctypes - unloading implicitly loaded dlls

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • pigmartian

    ctypes - unloading implicitly loaded dlls

    (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.Loa dLibrary('/path1/libA.dll')
    A.foo() # implicitly uses '/path1/libC.dll'

    _ctypes.FreeLib rary(A._handle)

    # CRASH!
    B = ctypes.cdll.Loa dLibrary('/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
  • Nick Craig-Wood

    #2
    Re: ctypes - unloading implicitly loaded dlls

    pigmartian <scottpig1@comc ast.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.Loa dLibrary('/path1/libA.dll')
    A.foo() # implicitly uses '/path1/libC.dll'
    >
    _ctypes.FreeLib rary(A._handle)
    >
    # CRASH!
    B = ctypes.cdll.Loa dLibrary('/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.LoadLibr ary() 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 <nick@craig-wood.com-- http://www.craig-wood.com/nick

    Comment

    • pigmartian

      #3
      Re: ctypes - unloading implicitly loaded dlls

      Nick Craig-Wood wrote:
      You could try loading C explicitly with ctypes.LoadLibr ary() 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

      Comment

      Working...