Author: Armin Rigo <ar...@tunes.org> Branch: Changeset: r3096:93e213825746 Date: 2018-02-15 09:21 +0100 http://bitbucket.org/cffi/cffi/changeset/93e213825746/
Log: Trying to fix ffi.dlopen() for unicode filenames on Windows diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c --- a/c/_cffi_backend.c +++ b/c/_cffi_backend.c @@ -3989,7 +3989,7 @@ static PyObject *dl_repr(DynLibObject *dlobj) { - return PyText_FromFormat("<clibrary '%s'>", dlobj->dl_name); + return PyText_FromFormat("<clibrary %s>", dlobj->dl_name); } static PyObject *dl_load_function(DynLibObject *dlobj, PyObject *args) @@ -4013,7 +4013,7 @@ if (funcptr == NULL) { const char *error = dlerror(); PyErr_Format(PyExc_AttributeError, - "function/symbol '%s' not found in library '%s': %s", + "function/symbol '%s' not found in library %s: %s", funcname, dlobj->dl_name, error); return NULL; } @@ -4040,7 +4040,7 @@ const char *error = dlerror(); if (error != NULL) { PyErr_Format(PyExc_KeyError, - "variable '%s' not found in library '%s': %s", + "variable '%s' not found in library %s: %s", varname, dlobj->dl_name, error); return NULL; } @@ -4064,7 +4064,7 @@ if (data == NULL) { const char *error = dlerror(); PyErr_Format(PyExc_KeyError, - "variable '%s' not found in library '%s': %s", + "variable '%s' not found in library %s: %s", varname, dlobj->dl_name, error); return NULL; } @@ -4116,8 +4116,9 @@ static PyObject *b_load_library(PyObject *self, PyObject *args) { char *filename_or_null, *printable_filename; + PyObject *s = NULL; void *handle; - DynLibObject *dlobj; + DynLibObject *dlobj = NULL; int flags = 0; if (PyTuple_GET_SIZE(args) == 0 || PyTuple_GET_ITEM(args, 0) == Py_None) { @@ -4126,31 +4127,61 @@ &dummy, &flags)) return NULL; filename_or_null = NULL; - } - else if (!PyArg_ParseTuple(args, "et|i:load_library", - Py_FileSystemDefaultEncoding, &filename_or_null, - &flags)) - return NULL; - + printable_filename = "<None>"; + } + else + { + printable_filename = NULL; + s = PyObject_Repr(PyTuple_GET_ITEM(args, 0)); + if (s != NULL) { + printable_filename = PyText_AsUTF8(s); + } + if (printable_filename == NULL) { + PyErr_Clear(); + printable_filename = "?"; + } + +#ifdef MS_WIN32 + { + Py_UNICODE *filenameW; + if (PyArg_ParseTuple(args, "u|i:load_library", &filenameW, &flags)) + { + handle = dlopenW(filenameW); + goto got_handle; + } + PyErr_Clear(); + } +#endif + if (!PyArg_ParseTuple(args, "et|i:load_library", + Py_FileSystemDefaultEncoding, &filename_or_null, + &flags)) + goto error; + } if ((flags & (RTLD_NOW | RTLD_LAZY)) == 0) flags |= RTLD_NOW; - printable_filename = filename_or_null ? filename_or_null : "<None>"; handle = dlopen(filename_or_null, flags); + +#ifdef MS_WIN32 + got_handle: +#endif if (handle == NULL) { const char *error = dlerror(); PyErr_Format(PyExc_OSError, "cannot load library %s: %s", printable_filename, error); - return NULL; + goto error; } dlobj = PyObject_New(DynLibObject, &dl_type); if (dlobj == NULL) { dlclose(handle); - return NULL; + goto error; } dlobj->dl_handle = handle; dlobj->dl_name = strdup(printable_filename); + + error: + Py_XDECREF(s); return (PyObject *)dlobj; } diff --git a/c/misc_win32.h b/c/misc_win32.h --- a/c/misc_win32.h +++ b/c/misc_win32.h @@ -192,7 +192,12 @@ static void *dlopen(const char *filename, int flag) { - return (void *)LoadLibrary(filename); + return (void *)LoadLibraryA(filename); +} + +static void *dlopenW(const wchar_t *filename) +{ + return (void *)LoadLibraryW(filename); } static void *dlsym(void *handle, const char *symbol) diff --git a/testing/cffi0/test_ownlib.py b/testing/cffi0/test_ownlib.py --- a/testing/cffi0/test_ownlib.py +++ b/testing/cffi0/test_ownlib.py @@ -114,8 +114,12 @@ if sys.platform == 'win32': import os # did we already build it? - if os.path.exists(str(udir.join('testownlib.dll'))): - cls.module = str(udir.join('testownlib.dll')) + if cls.Backend is CTypesBackend: + dll_path = str(udir) + '\\testownlib1.dll' # only ascii for the ctypes backend + else: + dll_path = str(udir) + '\\' + (u+'testownlib\u03be.dll') # non-ascii char + if os.path.exists(dll_path): + cls.module = dll_path return # try (not too hard) to find the version used to compile this python # no mingw @@ -135,8 +139,9 @@ if os.path.isfile(vcvarsall): cmd = '"%s" %s' % (vcvarsall, arch) + ' & cl.exe testownlib.c ' \ ' /LD /Fetestownlib.dll' - subprocess.check_call(cmd, cwd = str(udir), shell=True) - cls.module = str(udir.join('testownlib.dll')) + subprocess.check_call(cmd, cwd = str(udir), shell=True) + os.rename(str(udir) + '\\testownlib.dll', dll_path) + cls.module = dll_path else: subprocess.check_call( 'cc testownlib.c -shared -fPIC -o testownlib.so', _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit