Author: Armin Rigo <[email protected]>
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
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit