[pypy-svn] r61736 - in pypy/trunk/pypy: lib/app_test/ctypes_tests module/_rawffi module/_rawffi/test rlib

afa at codespeak.net afa at codespeak.net
Wed Feb 11 15:58:10 CET 2009


Author: afa
Date: Wed Feb 11 15:58:09 2009
New Revision: 61736

Modified:
   pypy/trunk/pypy/lib/app_test/ctypes_tests/test_loading.py
   pypy/trunk/pypy/module/_rawffi/interp_rawffi.py
   pypy/trunk/pypy/module/_rawffi/test/test__rawffi.py
   pypy/trunk/pypy/rlib/libffi.py
Log:
Implement access to dll functions by ordinal.
Now all ctypes tests pass on win32 :-)


Modified: pypy/trunk/pypy/lib/app_test/ctypes_tests/test_loading.py
==============================================================================
--- pypy/trunk/pypy/lib/app_test/ctypes_tests/test_loading.py	(original)
+++ pypy/trunk/pypy/lib/app_test/ctypes_tests/test_loading.py	Wed Feb 11 15:58:09 2009
@@ -61,8 +61,9 @@
                 WinDLL("coredll").GetModuleHandleW
 
         def test_load_ordinal_functions(self):
-            import _ctypes_test
-            dll = WinDLL(_ctypes_test.__file__)
+            import conftest
+            _ctypes_test = str(conftest.sofile)
+            dll = CDLL(_ctypes_test)
             # We load the same function both via ordinal and name
             func_ord = dll[2]
             func_name = dll.GetString

Modified: pypy/trunk/pypy/module/_rawffi/interp_rawffi.py
==============================================================================
--- pypy/trunk/pypy/module/_rawffi/interp_rawffi.py	(original)
+++ pypy/trunk/pypy/module/_rawffi/interp_rawffi.py	Wed Feb 11 15:58:09 2009
@@ -142,7 +142,7 @@
         self.w_cache = space.newdict()
         self.space = space
 
-    def ptr(self, space, name, w_argtypes, w_restype, flags=FUNCFLAG_CDECL):
+    def ptr(self, space, w_name, w_argtypes, w_restype, flags=FUNCFLAG_CDECL):
         """ Get a pointer for function name with provided argtypes
         and restype
         """
@@ -150,7 +150,7 @@
         w = space.wrap
         argtypes_w = space.viewiterable(w_argtypes)
         w_argtypes = space.newtuple(argtypes_w)
-        w_key = space.newtuple([w(name), w_argtypes, w(resshape)])
+        w_key = space.newtuple([w_name, w_argtypes, w(resshape)])
         try:
             return space.getitem(self.w_cache, w_key)
         except OperationError, e:
@@ -159,16 +159,34 @@
             else:
                 raise
         ffi_argtypes, argletters = unpack_argshapes(space, w_argtypes)
-        try:
-            ptr = self.cdll.getrawpointer(name, ffi_argtypes, ffi_restype,
-                                          flags)
-            w_funcptr = W_FuncPtr(space, ptr, argletters, resshape)
-            space.setitem(self.w_cache, w_key, w_funcptr)
-            return w_funcptr
-        except KeyError:
-            raise OperationError(space.w_AttributeError, space.wrap(
-                "No symbol %s found in library %s" % (name, self.name)))
-    ptr.unwrap_spec = ['self', ObjSpace, str, W_Root, W_Root, int]
+
+        if space.is_true(space.isinstance(w_name, space.w_str)):
+            name = space.str_w(w_name)
+
+            try:
+                ptr = self.cdll.getrawpointer(name, ffi_argtypes, ffi_restype,
+                                              flags)
+            except KeyError:
+                raise OperationError(space.w_AttributeError, space.wrap(
+                    "No symbol %s found in library %s" % (name, self.name)))
+        
+        elif (_MS_WINDOWS and
+              space.is_true(space.isinstance(w_name, space.w_int))):
+            ordinal = space.int_w(w_name)
+            try:
+                ptr = self.cdll.getrawpointer_byordinal(ordinal, ffi_argtypes,
+                                                        ffi_restype, flags)
+            except KeyError:
+                raise OperationError(space.w_AttributeError, space.wrap(
+                    "No symbol %d found in library %s" % (ordinal, self.name)))
+        else:
+            raise OperationError(space.w_TypeError, space.wrap(
+                "function name must be string or integer"))
+
+        w_funcptr = W_FuncPtr(space, ptr, argletters, resshape)
+        space.setitem(self.w_cache, w_key, w_funcptr)
+        return w_funcptr
+    ptr.unwrap_spec = ['self', ObjSpace, W_Root, W_Root, W_Root, int]
 
     def getaddressindll(self, space, name):
         try:

Modified: pypy/trunk/pypy/module/_rawffi/test/test__rawffi.py
==============================================================================
--- pypy/trunk/pypy/module/_rawffi/test/test__rawffi.py	(original)
+++ pypy/trunk/pypy/module/_rawffi/test/test__rawffi.py	Wed Feb 11 15:58:09 2009
@@ -140,6 +140,11 @@
             inp.y *= 3;
             return inp;
         }
+
+        int AAA_first_ordinal_function()
+        {
+            return 42;
+        }
         
         '''))
         symbols = """get_char char_check get_raw_pointer
@@ -153,6 +158,7 @@
                      static_int static_double
                      sum_x_y
                      give perturb
+                     AAA_first_ordinal_function
                   """.split()
         eci = ExternalCompilationInfo(export_symbols=symbols)
         return str(platform.compile([c_file], eci, 'x', standalone=False))
@@ -195,6 +201,16 @@
         assert isinstance(func, _rawffi.FuncPtr)
         raises(AttributeError, "libc.xxxxxxxxxxxxxx")
 
+    def test_byordinal(self):
+        if not self.iswin32:
+            skip("win32 specific")
+        import _rawffi
+        lib = _rawffi.CDLL(self.lib_name)
+        # This will call the ordinal function numbered 1
+        # my compiler seems to order them alphabetically:
+        # AAA_first_ordinal_function
+        assert lib.ptr(1, [], 'i')()[0] == 42
+
     def test_getchar(self):
         import _rawffi
         lib = _rawffi.CDLL(self.lib_name)

Modified: pypy/trunk/pypy/rlib/libffi.py
==============================================================================
--- pypy/trunk/pypy/rlib/libffi.py	(original)
+++ pypy/trunk/pypy/rlib/libffi.py	Wed Feb 11 15:58:09 2009
@@ -248,6 +248,10 @@
         # XXX rffi.cast here...
         return res
 
+    def dlsym_byordinal(handle, index):
+        # Never called
+        raise KeyError(index)
+    
     libc_name = ctypes.util.find_library('c')
 
 if _WIN32:
@@ -272,6 +276,15 @@
         # XXX rffi.cast here...
         return res
 
+    def dlsym_byordinal(handle, index):
+        # equivalent to MAKEINTRESOURCEA
+        intresource = rffi.cast(rffi.CCHARP, r_uint(index) & 0xFFFF)
+        res = rwin32.GetProcAddress(handle, intresource)
+        if not res:
+            raise KeyError(name)
+        # XXX rffi.cast here...
+        return res
+    
     FormatError = rwin32.FormatError
     LoadLibrary = rwin32.LoadLibrary
 
@@ -573,6 +586,13 @@
         return RawFuncPtr(name, argtypes, restype, dlsym(self.lib, name),
                           flags=flags)
 
+    def getrawpointer_byordinal(self, ordinal, argtypes, restype,
+                                flags=FUNCFLAG_CDECL):
+        # these arguments are already casted to proper ffi
+        # structures!
+        return RawFuncPtr(name, argtypes, restype,
+                          dlsym_byordinal(self.lib, ordinal), flags=flags)
+
     def getaddressindll(self, name):
         return dlsym(self.lib, name)
 



More information about the Pypy-commit mailing list