9

I'm afriad I couldn't find a simple answer for this on the internet, so maybe there will be one in the future because of this question!

I'm using pywiiuse, a python wrapper for the C wiiuse library on windows. I've gotten several plain C examples working simply by including the dll, header, and library in the directory of the source.

However, I'm wondering where to put the dll so that pywiiuse will find it. A look at the source shows that it is loaded as follows:

dll = ctypes.cdll.wiiuse

Running examples yields a module not found exception when I have the dll in the same directory as my test example.

Where does python look for the dll?

Donald Duck
  • 8,409
  • 22
  • 75
  • 99
cemulate
  • 2,305
  • 1
  • 34
  • 48
  • 1
    I believe it searches in the same place Windows would search for DLLs - so in the directory of the Python exe and in Windows/System32. – li.davidm Jun 25 '11 at 01:53
  • Is there any option I might run python with to change this by any chance? I don't mind putting it in there if I have to, but I'd prefer to just keep it in the working directory. – cemulate Jun 25 '11 at 03:31

2 Answers2

7

The Windows DLL search order is documented on MSDN. It's not Python-specific, and there is no way to change the search order from a command-line option. (But see the linked article for other ways to influence the search order.)

The source to ctypes/__init__.py does:

from _ctypes import LoadLibrary as _dlopen

I wasn't able to find the definition of LoadLibrary in _ctypes.c, but presumably it is a wrapper for the Windows LoadLibraryEx function that behaves similarly to the POSIX dlopen function, because that is how it is used.

If you can modify the Python source to use the ctypes.CDLL constructor instead, it should work:

folder = os.path.dirname(os.path.abspath(__file__))
dll_path = os.path.join(folder, "wiiuse.dll")    
dll = ctypes.CDLL(dll_path)

If that isn't viable, you may be able to monkey-patch ctypes to handle this specific case, but that seems a bit dangerous. Perhaps just copying the DLL to be in the same folder with the Python DLL would be the easiest alternative.

Daniel Pryden
  • 59,486
  • 16
  • 97
  • 135
  • 2
    So it's out of python's hands then. I just remembered that my file is not the executable, python is the executable. Haha. – cemulate Jun 25 '11 at 06:51
1

Loading a custom DLL in a custom folder using the Windows API takes a few steps:

  1. Confirm where they are using file system calls - something like a whole heap of lines looking something like: if path.exists(cwd() + "bin" + "mydll.dll"): return cwd() + "bin". Or if you're feeling brave just set the path.
  2. Use ctypes to load the Kernel32.dll - it knows where that one is natively.
  3. Load SetDllDirectory from Kernel32.dll. Call it with the path where you know where your dlls are.
  4. Now LoadLibrary will search for Dlls in that folder, so you can use ctypes to load your dll and call your functions.
Ash
  • 1,956
  • 1
  • 14
  • 15