Skip to content

Commit

Permalink
Win32: pass the flags from dlopen() to LoadLibraryEx() (#65)
Browse files Browse the repository at this point in the history
* Win32: pass the flags from dlopen() to LoadLibraryEx()

Includes a default handling if flags==0, similar to the one in ctypes.

* Fix a compiler warning

* Document the new behavior of ffi.dlopen()
  • Loading branch information
arigo authored Feb 21, 2024
1 parent 0619e5e commit e59ec8f
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 5 deletions.
8 changes: 8 additions & 0 deletions doc/source/cdef.rst
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,14 @@ Useful if you have special needs (e.g. you need the GNU extension
automatically if the FFI object is garbage-collected (but you can still
call ``ffi.dlclose()`` explicitly if needed).

*New in version 1.17:* on Windows, ``ffi.dlopen(filename, flags=0)`` now
passes the flags to ``LoadLibraryEx()``. Moreover, if you use the
default value of 0 but ``filename`` contains a slash or backslash
character, it will instead use
``LOAD_LIBRARY_SEARCH_DEFAULT_DIRS | LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR``.
This ensures that dependent DLLs from the same path are also found.
It is what ctypes does too.


.. _set_source:

Expand Down
2 changes: 1 addition & 1 deletion src/c/_cffi_backend.c
Original file line number Diff line number Diff line change
Expand Up @@ -4570,7 +4570,7 @@ static void *b_do_dlopen(PyObject *args, const char **p_printable_filename,
if (sz1 < 0)
return NULL;
w1[sz1] = 0;
handle = dlopenW(w1);
handle = dlopenWinW(w1, flags);
goto got_handle;
}
PyErr_Clear();
Expand Down
24 changes: 20 additions & 4 deletions src/c/misc_win32.h
Original file line number Diff line number Diff line change
Expand Up @@ -191,14 +191,30 @@ static PyObject *b_getwinerror(PyObject *self, PyObject *args, PyObject *kwds)
#define RTLD_GLOBAL 0
#define RTLD_LOCAL 0

static void *dlopen(const char *filename, int flag)
static void *dlopen(const char *filename, int flags)
{
return (void *)LoadLibraryA(filename);
if (flags == 0) {
for (const char *p = filename; *p != 0; p++)
if (*p == '\\' || *p == '/') {
flags = LOAD_LIBRARY_SEARCH_DEFAULT_DIRS |
LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR;
break;
}
}
return (void *)LoadLibraryExA(filename, NULL, flags);
}

static void *dlopenW(const wchar_t *filename)
static void *dlopenWinW(const wchar_t *filename, int flags)
{
return (void *)LoadLibraryW(filename);
if (flags == 0) {
for (const wchar_t *p = filename; *p != 0; p++)
if (*p == '\\' || *p == '/') {
flags = LOAD_LIBRARY_SEARCH_DEFAULT_DIRS |
LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR;
break;
}
}
return (void *)LoadLibraryExW(filename, NULL, flags);
}

static void *dlsym(void *handle, const char *symbol)
Expand Down

0 comments on commit e59ec8f

Please sign in to comment.