Python: wrapper for C++ requires access to .dll files - python

I made a Python wrapper for an SDK written in C++ using SWIG and built using Microsoft Visual Studio 2010 in Windows 7.
It's been a success, with the module.py and _module.pyd being generated. However, this wrapper heavily depends on a couple .dll files located in the SDK folder outside PythonXY folder.
After I moved the module.py and module.pyd into PythonXY/Lib/site-packages/, and tried running import module, the following error occurs:
ImportError: DLL load failed: The specified module could not be found.
Then, I tried to change the Python working directory to the directory where the .dll files exist, using os.chdir() method from Python module os. This time, running import module output no error. I continued to access the wrapped C++ classes and functions and they worked just fine.
My questions are:
How can I "link" the path containing the .dll files so whenever I want to use module, I don't have to change the working directory?
Is there any way to append additional working directory aside from Python default working directory from within the Python source file? (i.e. not from PATH configuration on Windows)
Is there any way I can link the wrapper with those .dll files dynamically? Meaning that let say the files are copied to another machine and the .dll files are stored in different absolute path directory, the import module would still work?
The point is I want to make this wrapper as portable as possible, across multiple Windows machine.
Thank you.

I found a solution to let module.py find _module.pyd.
Basically, create a new file called module.pth and save it in the same directory as module.py. In this case, the directory is PythonXY/Lib/site-packages/.
Let say you place your _module.pyd inside a directory called _modulelib (PythonXY/Lib/site-packages/_modulelib/), then the content of module.pth should be like this:
_modulelib

Related

Compiling the Python Interface for Caffe using CMake

On Ubuntu, I have downloaded Caffe to ~/caffe, and compiled it using cmake with the CMakeLists.txt file that it comes with. I now want to start using the python interface. According to the examples, I need to add ~/caffe/python to the PYTHONPATH variable in my .bashrc file. Then, I need to use use import caffe in a python script. However, this gives me the error: ImportError: No module named 'caffe'.
If I use the line import caffe in my python script, this means that there must exist a file called caffe.py in the directories defined by PYTHONPATH. Is that correct? However, I cannot find any files called caffe.py on my system. But the CMakeLists.txt file is supposed to build the python files, and has the line add_subdirectory(python).
Does anybody have any experience with this? Had anybody got the python interface working by compiling with cmake?
Thanks.
You do not need to have caffe.py in ~/caffe/python. In this case you should have a subfolder ~/caffe/python/caffe that should have __init__.py file in this subfolder. Make sure you have ~caffe/python/caffe/_caffe.so file - this shared object should be created during compilation.
It may be the case that you added the right folder to your .bashrc, but have you loaded/sourced the file after updating it?

Keeping the .dll and .pyd files in other directory

I am using cx_Freeze to convert Python scripts to Windows executable. I am using cxfreeze script present in the Scripts directory. I want the executable generated by cxfreeze to be in a different directory and the .dll's and .pyd's in a different one. When I tried to put the two of them in separate directories the .exe did not work I got
The application has failed to start because python33.dll was not found. Try reinstalling to fix this problem
I know this happends because the executable and (dll's & .pyd's) are located in different directories. Is there a way to keep them in different directories ?
I am using the following command to generate the executable
C:\Python33\Scripts>cxfreeze C:\Users\me\Desktop\setup.py --target-name=setup.exe --target-dir=C:\Users\me\Desktop\new_dir
Python for Windows really requires that the main pythonXX.dll (in this case, python33.dll) exists in C:\windows\system32\
In all of our various combinations of installing Python to different locations, network drives, etc. we've always had to use a little batch file to copy pythonXX.dll into the system32 dir.
I don't think PATH manipulation will work for you, just try copying the dll to system32 and see if your issues go away.
Then again, if you installed another version of Python to say C:\Python33 , then that windows-based installer will do this for you, and you'll be able to run your other Python location.

Error importing a .pyd file (as a python module) from a .pyo file

I am running pygame (for Python) on Windows. I have some .pyo files and some .pyd files. I have another script for somewhere else that is trying to import one of the .pyd files as a module but I keep getting the error that no such module exists.
Do .pyo files have issues importing .pyd files as modules? What can I do to solve this issue?
It's typically because of one or more of the following:
The .pyd is not in your current path (you said it was in the same folder so that should not be the problem)
A DLL the .pyd depends on is not in your current path. Locate the missing DLL's using depends.exe or its modern rewrite and either copy these dll's to the same folder or add the containing directories to your system path
You're using a debug version of python. Then the module must be renamed from xyz.pyd to xyz_d.pyd.

DLL not loaded from documented search path

I have a process which is loading a DLL from a place not listed in the documented search order (docs linked below). I want to know why.
Here's the description of my setup:
I have a folder 'c:\foo' containing a.dll and b.dll.
I have a python script also stored in c:\foo.
The python script does a LoadLibrary('c:/foo/a.dll') (via ctypes)
a.dll is linked against the import library for b.dll (ie using implicit linking).
I run the python script with a current directory of, say, c:. It could be anything.
b.dll is loaded from c:\foo, even though that isn't on the search path.
Looking at the process monitor trace, I can see that all the documented search paths were tried first, and all failed. Then the python process tried and failed to open "C:\WINDOWS\assembly\GAC\Microsoft.VC80.CRT.mui\8.0.50727.4053_en-US_1fc8b3b9a1e18e3b\Microsoft.VC80.CRT.mui.DLL", then it opened c:\foo\b.dll.
So, it seems to be that the a.dll's directory is being searched for b.dll even though the docs don't say it should be. Also, this happens after looking on the system path, which is mad. Can anyone shed any light on this?
The same thing happens with a MatLab script that also uses a.dll.
I'm running Windows XP SP 3.
This MSDN article explains the default search order. I quote:
The directory specified by lpFileName.
The system directory. Use the GetSystemDirectory function to get the path of this directory.
The 16-bit system directory. There is no function that obtains the path of this directory, but it is searched.
The Windows directory. Use the GetWindowsDirectory function to get the path of this directory.
The current directory.
The directories that are listed in the PATH environment variable. Note that this does not include the per-application path specified by the App Paths registry key. The App Paths key is not used when computing the DLL search path.
a.dll is probably using runtime dynamic linking as a last resort
http://msdn.microsoft.com/en-us/library/ms686944%28VS.85%29.aspx

using a "temporary files" folder in python

I recently wrote a script which queries PyPI and downloads a package; however, the package gets downloaded to a user defined folder.
I`d like to modify the script in such a way that my downloaded files go into a temporary folder, if the folder is not specified.
The temporary-files folder in *nix machines is "/tmp" ; would there be any Python method I could use to find out the temporary-files folder in a particular machine?
If not, could someone suggest an alternative to this problem?
Python has a built-in module for using temporary files and folders. You probably want tempfile.mkdtemp().
Perhaps the tempfile module?

Categories

Resources