[pypy-commit] pypy win-ordinal: add ordinal function handling to libffi, expose in module\_ffi

mattip noreply at buildbot.pypy.org
Wed Jun 6 17:36:18 CEST 2012


Author: Matti Picus <matti.picus at gmail.com>
Branch: win-ordinal
Changeset: r55439:5b456796daa4
Date: 2012-06-06 18:34 +0300
http://bitbucket.org/pypy/pypy/changeset/5b456796daa4/

Log:	add ordinal function handling to libffi, expose in module\_ffi

diff --git a/pypy/module/_ffi/interp_funcptr.py b/pypy/module/_ffi/interp_funcptr.py
--- a/pypy/module/_ffi/interp_funcptr.py
+++ b/pypy/module/_ffi/interp_funcptr.py
@@ -15,6 +15,48 @@
 from pypy.rlib.objectmodel import we_are_translated
 from pypy.module._ffi.type_converter import FromAppLevelConverter, ToAppLevelConverter
 
+import os
+if os.name == 'nt':
+    def _getfunc(space, CDLL, w_name, w_argtypes, w_restype):
+        argtypes_w, argtypes, w_restype, restype = unpack_argtypes(space,
+                                                                   w_argtypes,
+                                                                   w_restype)
+        if space.isinstance_w(w_name, space.w_str):
+            name = space.str_w(w_name)
+            try:
+                func = CDLL.cdll.getpointer(name, argtypes, restype, 
+                                                flags = CDLL.flags)
+            except KeyError:
+                raise operationerrfmt(space.w_AttributeError,
+                                 "No symbol %s found in library %s", name, CDLL.name)
+
+            return W_FuncPtr(func, argtypes_w, w_restype)
+        elif space.isinstance_w(w_name, space.w_int):
+            ordinal = space.int_w(w_name)
+            try:
+                func = CDLL.cdll.getpointer_by_ordinal(ordinal, argtypes, restype, 
+                                                flags = CDLL.flags)
+            except KeyError:
+                raise operationerrfmt(space.w_AttributeError,
+                                 "No ordinal %d found in library %s", ordinal, CDLL.name)
+            return W_FuncPtr(func, argtypes_w, w_restype)
+        else:
+            raise OperationError(space.w_TypeError, 
+                    space.wrap('function name must be a string or integer'))
+else:    
+    @unwrap_spec(name=str)
+    def _getfunc(space, CDLL, name, w_argtypes, w_restype):
+        argtypes_w, argtypes, w_restype, restype = unpack_argtypes(space,
+                                                                   w_argtypes,
+                                                                   w_restype)
+        try:
+            func = CDLL.cdll.getpointer(name, argtypes, restype, 
+                                            flags = CDLL.flags)
+        except KeyError:
+            raise operationerrfmt(space.w_AttributeError,
+                                  "No symbol %s found in library %s", name, CDLL.name)
+
+        return W_FuncPtr(func, argtypes_w, w_restype)
 
 def unwrap_ffitype(space, w_argtype, allow_void=False):
     res = w_argtype.get_ffitype()
@@ -271,19 +313,8 @@
             raise operationerrfmt(space.w_OSError, '%s: %s', self.name,
                                   e.msg or 'unspecified error')
 
-    @unwrap_spec(name=str)
-    def getfunc(self, space, name, w_argtypes, w_restype):
-        argtypes_w, argtypes, w_restype, restype = unpack_argtypes(space,
-                                                                   w_argtypes,
-                                                                   w_restype)
-        try:
-            func = self.cdll.getpointer(name, argtypes, restype, 
-                                            flags = self.flags)
-        except KeyError:
-            raise operationerrfmt(space.w_AttributeError,
-                                  "No symbol %s found in library %s", name, self.name)
-
-        return W_FuncPtr(func, argtypes_w, w_restype)
+    def getfunc(self, space, w_name, w_argtypes, w_restype):
+        return _getfunc(space, self, w_name, w_argtypes, w_restype)
 
     @unwrap_spec(name=str)
     def getaddressindll(self, space, name):
diff --git a/pypy/module/_ffi/test/test_funcptr.py b/pypy/module/_ffi/test/test_funcptr.py
--- a/pypy/module/_ffi/test/test_funcptr.py
+++ b/pypy/module/_ffi/test/test_funcptr.py
@@ -627,4 +627,15 @@
                             types.void, FUNCFLAG_STDCALL)
         sleep(10)
 
- 
+    def test_by_ordinal(self):
+        """
+            int DLLEXPORT AAA_first_ordinal_function()
+            {
+                return 42;
+            }
+        """
+        from _ffi import CDLL, types
+        libfoo = CDLL(self.libfoo_name)
+        f_name = libfoo.getfunc('AAA_first_ordinal_function', [], types.sint)
+        f_ordinal = libfoo.getfunc(1, [], types.sint)
+        assert f_name.getaddr() == f_ordinal.getaddr()
diff --git a/pypy/rlib/libffi.py b/pypy/rlib/libffi.py
--- a/pypy/rlib/libffi.py
+++ b/pypy/rlib/libffi.py
@@ -415,6 +415,10 @@
         return Func(name, argtypes, restype, dlsym(self.lib, name),
                     flags=flags, keepalive=self)
 
+    def getpointer_by_ordinal(self, name, argtypes, restype,
+                              flags=FUNCFLAG_CDECL):
+        return Func(name, argtypes, restype, dlsym_byordinal(self.lib, name),
+                    flags=flags, keepalive=self)
     def getaddressindll(self, name):
         return dlsym(self.lib, name)
 
@@ -423,6 +427,11 @@
         def getpointer(self, name, argtypes, restype, flags=FUNCFLAG_STDCALL):
             return Func(name, argtypes, restype, dlsym(self.lib, name),
                         flags=flags, keepalive=self)
+    def getpointer_by_ordinal(self, name, argtypes, restype,
+                              flags=FUNCFLAG_STDCALL):
+        return Func(name, argtypes, restype, dlsym_byordinal(self.lib, name),
+                    flags=flags, keepalive=self)
+
 # ======================================================================
 
 @jit.oopspec('libffi_struct_getfield(ffitype, addr, offset)')
diff --git a/pypy/rlib/test/test_libffi.py b/pypy/rlib/test/test_libffi.py
--- a/pypy/rlib/test/test_libffi.py
+++ b/pypy/rlib/test/test_libffi.py
@@ -222,7 +222,7 @@
                 if meth.__doc__ is not None and '{' in meth.__doc__:
                     snippets.append(meth.__doc__)
                     import re
-                    for match in re.finditer(" ([a-z_]+)\(", meth.__doc__):
+                    for match in re.finditer(" ([A-Za-z_]+)\(", meth.__doc__):
                         exports.append(match.group(1))
         #
         c_file.write(STANDARD_DEFINES + str(py.code.Source('\n'.join(snippets))))
@@ -557,10 +557,10 @@
     if os.name == 'nt':
         def test_stdcall_simple(self):
             """
-                int __stdcall std_diff_xy(int x, Signed y)
-                {
-                    return x - y;
-                }
+            int __stdcall std_diff_xy(int x, Signed y)
+            {
+                return x - y;
+            }
             """
             libfoo = self.get_libfoo()
             func = (libfoo, 'std_diff_xy', [types.sint, types.signed], types.sint)
@@ -575,5 +575,19 @@
             else:
                 assert 0, 'wrong calling convention should have raised'
 
+        def test_by_ordinal(self):
+            """
+            int AAA_first_ordinal_function()
+            {
+                return 42;
+            }
+            """
+            libfoo = self.get_libfoo()
+            f_by_name = libfoo.getpointer('AAA_first_ordinal_function' ,[],
+                                          types.uint)
+            f_by_ordinal = libfoo.getpointer_by_ordinal(1 ,[], types.uint)
+            print dir(f_by_name)
+            assert f_by_name.funcsym == f_by_ordinal.funcsym
+
 
         


More information about the pypy-commit mailing list