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

Reply via email to