Commits

mattip  committed ba86c4d

support ordinals

  • Participants
  • Parent commits 6d09b1c
  • Branches win32-stdlib

Comments (0)

Files changed (3)

File pypy/module/_ffi/interp_funcptr.py

 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)
+        elif space.isinstance_w(w_name, space.w_int):
+            name = space.int_w(w_name)
+        else:
+            raise OperationError(space.ValueError, 
+                    space.wrap('name must be str or int'))
+        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)
+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()
             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):

File pypy/module/_ffi/test/test_funcptr.py

         space = gettestobjspace(usemodules=('_ffi', '_rawffi'))
         cls.space = space
         cls.w_iswin32 = space.wrap(sys.platform == 'win32')
-        cls.w_libfoo_name = space.wrap(cls.prepare_c_example())
+        cls.w_libfoo_name = space.wrap(cls.prepare_c_example()) 
         cls.w_libc_name = space.wrap(get_libc_name())
         libm_name = get_libm_name(sys.platform)
         cls.w_libm_name = space.wrap(libm_name)
                             types.void, FUNCFLAG_STDCALL)
         sleep(10)
 
- 
+    def test_ordinal_func(self):
+        """
+            DLLEXPORT int AAA_first_ordinal_function()
+            {
+                return 42;
+            }
+        """
+        if not self.iswin32:
+            skip("windows specific")
+        from _ffi import CDLL, types
+        libfoo = CDLL(self.libfoo_name)
+        f_name = libfoo.getfunc('AAA_first_ordinal_function', [], types.sint)
+        f_ord = libfoo.getfunc(1, [], types.sint)
+        assert f_name.getaddr() == f_ord.getaddr()

File pypy/rlib/libffi.py

 
 # ======================================================================
 
+def _dlsym_by_name_or_ord(lib, name):
+    if isinstance(name, str):
+        return dlsym(lib,name)
+    else:
+        return dlsym_byordinal(lib,name)
 
 # XXX: it partially duplicate the code in clibffi.py
 class CDLL(object):
             self.lib = rffi.cast(DLLHANDLE, 0)
 
     def getpointer(self, name, argtypes, restype, flags=FUNCFLAG_CDECL):
-        return Func(name, argtypes, restype, dlsym(self.lib, name),
+        return Func(name, argtypes, restype, 
+                    _dlsym_by_name_or_ord(self.lib, name),
                     flags=flags, keepalive=self)
 
     def getaddressindll(self, name):
 if os.name == 'nt':
     class WinDLL(CDLL):
         def getpointer(self, name, argtypes, restype, flags=FUNCFLAG_STDCALL):
-            return Func(name, argtypes, restype, dlsym(self.lib, name),
+            return Func(name, argtypes, restype, 
+                        _dlsym_by_name_or_ord(self.lib, name),
                         flags=flags, keepalive=self)
 # ======================================================================