-
Notifications
You must be signed in to change notification settings - Fork 0
windows dll notes
On Windows, Python extension modules have file extensions .pyd
as in
myextension.pyd
.
DLLs are a problem for general windows builds because it can be tricky making sure your extension gets the right DLL.
Imagine you have a package like this:
mypackage/ myextension.pyd runtime.dll yourpackage/ yourextension.pyd runtime.dll
myextension.pyd
depends on my version of runtime.dll
, and
yourextension.pyd
depends on your version of runtime.dll
.
But, when I do: >>> import mypackage.myextension
, then myextension.pyd
gets loaded, as does my copy of runtime.dll
. When I then do >>> import
yourpackage.yourextension
, Windows sees that we already have a copy of
runtime.dll
, so doesn't load your copy of runtime.dll
. If these two
DLLs are not the same, this can cause nasty crashes, and crashes that depend on
the order in which the two pyd extensions get loaded.
We also need to make sure that the DLLs we need can be found when the Python extension gets loaded.
When Python loads an extension, it does it using the Windows LoadLibraryEx
call, like this:
hDLL = LoadLibraryEx(extension_path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
See: http://hg.python.org/cpython/file/3a1db0d2747e/Python/dynload_win.c#l195
LOAD_WITH_ALTERED_SEARCH_PATH
causes Windows to look for DLLs first in the
directory containing the extension (directory containing extension_path
)
(see DLL search path)
Specifically, if you do:
>>> import mypackage.myextension
and myextension.pyd
is in c:\Python27\Lib\site-packages\mypackage
, and
myextension.dll
loads runtime.dll
, then Windows will look for
runtime.dll
first in c:\Python27\Lib\site-packages\mypackage
.
A common situation is that you want to put all needed DLLs in one directory, but there are extensions loading these DLLs are all over the file tree.
For example, default builds of scipy using Mingw-w64 will depend on gcc and
gfortran run-time DLLs. There will be extensions needing these DLLs in several places in the scipy package tree. In that
case we may want to have a single directory called dlls
in the Scipy tree containing these
DLLs. We can put this directory on the DLL search path with DLL path tricks
used in this ctypes code fragment (thanks to Steve Dower for the
fragment, Carl Kleffner for finding it).
Some unsorted links that also seemed useful:
- DLL loading analysis with dependency walker
- Discussion of DLL options for the Glasgow Haskell Compiler
- A couple of useful posts on side-by-side assemblies and manifests on the
Visual Studio for Python forum:
- http://social.msdn.microsoft.com/Forums/vstudio/en-US/8aa6eb67-5429-41bf-bacb-3b6423e8edd1/vc-load-different-versions-of-the-dll-in-the-same-application?forum=vcgeneral
- http://social.msdn.microsoft.com/Forums/vstudio/en-US/b3eaa07f-7f92-4693-8aa1-b8fee0b92d2f/cannot-load-2-dlls-with-same-name-but-different-versions?forum=vcgeneral