[pypy-commit] cffi default: More Windows support for ffi.dlopen(), this time the out-of-line version
arigo
pypy.commits at gmail.com
Fri Feb 16 05:23:22 EST 2018
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r3100:5448f4eca09c
Date: 2018-02-16 11:22 +0100
http://bitbucket.org/cffi/cffi/changeset/5448f4eca09c/
Log: More Windows support for ffi.dlopen(), this time the out-of-line
version
diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c
--- a/c/_cffi_backend.c
+++ b/c/_cffi_backend.c
@@ -4145,49 +4145,56 @@
dl_methods, /* tp_methods */
};
-static PyObject *b_load_library(PyObject *self, PyObject *args)
-{
- char *filename_or_null, *printable_filename;
- PyObject *s = NULL;
+static void *b_do_dlopen(PyObject *args, char **p_printable_filename,
+ PyObject **p_temp)
+{
+ /* Logic to call the correct version of dlopen(). Returns NULL in case of error.
+ Otherwise, '*p_printable_filename' will point to a printable char version of
+ the filename (maybe utf-8-encoded). '*p_temp' will be set either to NULL or
+ to a temporary object that must be freed after looking at printable_filename.
+ */
void *handle;
- DynLibObject *dlobj = NULL;
+ char *filename_or_null;
int flags = 0;
-
+ *p_temp = NULL;
+
if (PyTuple_GET_SIZE(args) == 0 || PyTuple_GET_ITEM(args, 0) == Py_None) {
PyObject *dummy;
if (!PyArg_ParseTuple(args, "|Oi:load_library",
&dummy, &flags))
return NULL;
filename_or_null = NULL;
- printable_filename = "<None>";
+ *p_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 = "?";
- }
-
+ PyObject *s = PyTuple_GET_ITEM(args, 0);
#ifdef MS_WIN32
+ Py_UNICODE *filenameW;
+ if (PyArg_ParseTuple(args, "u|i:load_library", &filenameW, &flags))
{
- Py_UNICODE *filenameW;
- if (PyArg_ParseTuple(args, "u|i:load_library", &filenameW, &flags))
- {
- handle = dlopenW(filenameW);
- goto got_handle;
- }
- PyErr_Clear();
- }
+#if PY_MAJOR_VERSION < 3
+ s = PyUnicode_AsUTF8String(s);
+ if (s == NULL)
+ return NULL;
+ *p_temp = s;
+#endif
+ *p_printable_filename = PyText_AsUTF8(s);
+ if (*p_printable_filename == NULL)
+ return NULL;
+
+ 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;
+ Py_FileSystemDefaultEncoding, &filename_or_null, &flags))
+ return NULL;
+
+ *p_printable_filename = PyText_AsUTF8(s);
+ if (*p_printable_filename == NULL)
+ return NULL;
}
if ((flags & (RTLD_NOW | RTLD_LAZY)) == 0)
flags |= RTLD_NOW;
@@ -4199,10 +4206,23 @@
#endif
if (handle == NULL) {
const char *error = dlerror();
- PyErr_Format(PyExc_OSError, "cannot load library %s: %s",
- printable_filename, error);
+ PyErr_Format(PyExc_OSError, "cannot load library '%s': %s",
+ *p_printable_filename, error);
+ return NULL;
+ }
+ return handle;
+}
+
+static PyObject *b_load_library(PyObject *self, PyObject *args)
+{
+ char *printable_filename;
+ PyObject *temp;
+ void *handle;
+ DynLibObject *dlobj = NULL;
+
+ handle = b_do_dlopen(args, &printable_filename, &temp);
+ if (handle == NULL)
goto error;
- }
dlobj = PyObject_New(DynLibObject, &dl_type);
if (dlobj == NULL) {
@@ -4211,9 +4231,9 @@
}
dlobj->dl_handle = handle;
dlobj->dl_name = strdup(printable_filename);
-
+
error:
- Py_XDECREF(s);
+ Py_XDECREF(temp);
return (PyObject *)dlobj;
}
diff --git a/c/cdlopen.c b/c/cdlopen.c
--- a/c/cdlopen.c
+++ b/c/cdlopen.c
@@ -40,35 +40,18 @@
static PyObject *ffi_dlopen(PyObject *self, PyObject *args)
{
- char *filename_or_null, *printable_filename;
+ char *modname;
+ PyObject *temp, *result = NULL;
void *handle;
- int flags = 0;
- if (PyTuple_GET_SIZE(args) == 0 || PyTuple_GET_ITEM(args, 0) == Py_None) {
- PyObject *dummy;
- if (!PyArg_ParseTuple(args, "|Oi:load_library",
- &dummy, &flags))
- return NULL;
- filename_or_null = NULL;
+ handle = b_do_dlopen(args, &modname, &temp);
+ if (handle != NULL)
+ {
+ result = (PyObject *)lib_internal_new((FFIObject *)self,
+ modname, handle);
}
- else if (!PyArg_ParseTuple(args, "et|i:load_library",
- Py_FileSystemDefaultEncoding, &filename_or_null,
- &flags))
- return NULL;
-
- 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);
- if (handle == NULL) {
- const char *error = dlerror();
- PyErr_Format(PyExc_OSError, "cannot load library '%s': %s",
- printable_filename, error);
- return NULL;
- }
- return (PyObject *)lib_internal_new((FFIObject *)self,
- printable_filename, handle);
+ Py_XDECREF(temp);
+ return result;
}
static PyObject *ffi_dlclose(PyObject *self, PyObject *args)
diff --git a/testing/cffi1/test_re_python.py b/testing/cffi1/test_re_python.py
--- a/testing/cffi1/test_re_python.py
+++ b/testing/cffi1/test_re_python.py
@@ -1,8 +1,9 @@
-import sys
+import sys, os
import py
from cffi import FFI
from cffi import recompiler, ffiplatform, VerificationMissing
from testing.udir import udir
+from testing.support import u
def setup_module(mod):
@@ -35,6 +36,13 @@
'globalconst42', 'globalconsthello']
)
outputfilename = ffiplatform.compile(str(tmpdir), ext)
+ if sys.platform == "win32":
+ # test with a non-ascii char
+ outputfn1 = outputfilename
+ ofn, oext = os.path.splitext(outputfn1)
+ outputfilename = ofn + (u+'\u03be') + oext
+ #print(repr(outputfn1) + ' ==> ' + repr(outputfilename))
+ os.rename(outputfn1, outputfilename)
mod.extmod = outputfilename
mod.tmpdir = tmpdir
#
@@ -107,12 +115,16 @@
from re_python_pysrc import ffi
lib = ffi.dlopen(extmod)
ffi.dlclose(lib)
+ if type(extmod) is not str: # unicode, on python 2
+ str_extmod = extmod.encode('utf-8')
+ else:
+ str_extmod = extmod
e = py.test.raises(ffi.error, ffi.dlclose, lib)
assert str(e.value).startswith(
- "library '%s' is already closed" % (extmod,))
+ "library '%s' is already closed" % (str_extmod,))
e = py.test.raises(ffi.error, getattr, lib, 'add42')
assert str(e.value) == (
- "library '%s' has been closed" % (extmod,))
+ "library '%s' has been closed" % (str_extmod,))
def test_constant_via_lib():
from re_python_pysrc import ffi
More information about the pypy-commit
mailing list