Why does python use relative instead of absolute path when calling LoadLibrary*

Hi, While looking at the import code of python for C extensions, I was wondering why we pass a relative path instead of an absolute path to LoadLibraryEx (see bottom for some context). In python 2.7, the full path existence was even checked before calling into LoadLibraryEx ( https://github.com/python/cpython/blob/2.7/Python/dynload_win.c#L189), but it looks like this check was removed in python 3.x branch. Is there any defined behaviour that depends on this path to be relative ? Context ----------- The reason why I am interested in this is the potential use of SetDllDirectory to share dlls between multiple python extensions. Currently, the only solutions I am aware of are: 1. putting the dlls in the PATH 2. bundling the dlls side by side the .pyd 3. patching packages to use preloading (using e.g. ctypes) I am investigating a solution 4, where the dlls would be put in a separate "private" directory only known of python itself, without the need to modify PATH. Patching python to use SetDllDirectory("some private paths specific to a python interpreter") works perfectly, except that it slightly changes the semantics of LoadLibraryEx not to look for dlls in the current directory. This breaks importing extensions built in place, unless I modify the call in ;https://github.com/python/cpython/blob/2.7/Python/dynload_win.c#L195 from: hDLL = LoadLibraryEx(pathname, NULL LOAD_WITH_ALTERED_SEARCH_PATH) to hDLL = LoadLibraryEx(pathbuf, NULL LOAD_WITH_ALTERED_SEARCH_PATH) That seems to work, but I am quite worried about changing any import semantics by accident. David

On Mar 11, 2015 3:36 PM, "David Cournapeau" <cournape@gmail.com> wrote:
Hi,
While looking at the import code of python for C extensions, I was
wondering why we pass a relative path instead of an absolute path to LoadLibraryEx (see bottom for some context).
In python 2.7, the full path existence was even checked before calling
into LoadLibraryEx ( https://github.com/python/cpython/blob/2.7/Python/dynload_win.c#L189), but it looks like this check was removed in python 3.x branch.
Is there any defined behaviour that depends on this path to be relative ?
Just a guess: does it have to do with resolving symlinks (w/ POSIX filesystems)?

On 3/11/15 9:36 PM, David Cournapeau wrote:
My two cents. According to the MSDN documentation, passing a relative path is actually undefined https://msdn.microsoft.com/en-us/library/windows/desktop/ms684179%28v=vs.85%... ---------------------------- LOAD_WITH_ALTERED_SEARCH_PATH 0x00000008 If this value is used and lpFileName specifies an absolute path, the system uses the alternate file search strategy discussed in the Remarks section to find associated executable modules that the specified module causes to be loaded. If this value is used and lpFileName specifies a relative path, the behavior is undefined. --------------------------- meaning that wpathname _must_ be absolute. https://github.com/python/cpython/blob/master/Python/dynload_win.c#L222

On Mar 11, 2015 3:36 PM, "David Cournapeau" <cournape@gmail.com> wrote:
Hi,
While looking at the import code of python for C extensions, I was
wondering why we pass a relative path instead of an absolute path to LoadLibraryEx (see bottom for some context).
In python 2.7, the full path existence was even checked before calling
into LoadLibraryEx ( https://github.com/python/cpython/blob/2.7/Python/dynload_win.c#L189), but it looks like this check was removed in python 3.x branch.
Is there any defined behaviour that depends on this path to be relative ?
Just a guess: does it have to do with resolving symlinks (w/ POSIX filesystems)?

On 3/11/15 9:36 PM, David Cournapeau wrote:
My two cents. According to the MSDN documentation, passing a relative path is actually undefined https://msdn.microsoft.com/en-us/library/windows/desktop/ms684179%28v=vs.85%... ---------------------------- LOAD_WITH_ALTERED_SEARCH_PATH 0x00000008 If this value is used and lpFileName specifies an absolute path, the system uses the alternate file search strategy discussed in the Remarks section to find associated executable modules that the specified module causes to be loaded. If this value is used and lpFileName specifies a relative path, the behavior is undefined. --------------------------- meaning that wpathname _must_ be absolute. https://github.com/python/cpython/blob/master/Python/dynload_win.c#L222
participants (4)
-
Brett Cannon
-
David Cournapeau
-
Stefano Borini
-
Wes Turner