Author: mattip <[email protected]>
Branch:
Changeset: r55551:eb506ba9e659
Date: 2012-06-10 22:47 +0300
http://bitbucket.org/pypy/pypy/changeset/eb506ba9e659/
Log: merge win-ordinal: a branch to expose finding functions in a dll via
ordinals to _ffi and ctypes
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,51 @@
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, w_name, w_argtypes, w_restype):
+ name = space.str_w(w_name)
+ 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 +316,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):
@@ -291,8 +325,9 @@
address_as_uint = rffi.cast(lltype.Unsigned,
self.cdll.getaddressindll(name))
except KeyError:
- raise operationerrfmt(space.w_ValueError,
- "No symbol %s found in library %s", name,
self.name)
+ raise operationerrfmt(
+ space.w_ValueError,
+ "No symbol %s found in library %s", name, self.name)
return space.wrap(address_as_uint)
@unwrap_spec(name='str_or_None', mode=int)
diff --git a/pypy/module/_ffi/interp_struct.py
b/pypy/module/_ffi/interp_struct.py
--- a/pypy/module/_ffi/interp_struct.py
+++ b/pypy/module/_ffi/interp_struct.py
@@ -56,8 +56,7 @@
class W__StructDescr(Wrappable):
- def __init__(self, space, name):
- self.space = space
+ def __init__(self, name):
self.w_ffitype = W_FFIType('struct %s' % name, clibffi.FFI_TYPE_NULL,
w_structdescr=self)
self.fields_w = None
@@ -69,7 +68,6 @@
raise operationerrfmt(space.w_ValueError,
"%s's fields has already been defined",
self.w_ffitype.name)
- space = self.space
fields_w = space.fixedview(w_fields)
# note that the fields_w returned by compute_size_and_alignement has a
# different annotation than the original: list(W_Root) vs list(W_Field)
@@ -104,11 +102,11 @@
return W__StructInstance(self, allocate=False, autofree=True,
rawmem=rawmem)
@jit.elidable_promote('0')
- def get_type_and_offset_for_field(self, name):
+ def get_type_and_offset_for_field(self, space, name):
try:
w_field = self.name2w_field[name]
except KeyError:
- raise operationerrfmt(self.space.w_AttributeError, '%s', name)
+ raise operationerrfmt(space.w_AttributeError, '%s', name)
return w_field.w_ffitype, w_field.offset
@@ -116,7 +114,7 @@
@unwrap_spec(name=str)
def descr_new_structdescr(space, w_type, name, w_fields=None):
- descr = W__StructDescr(space, name)
+ descr = W__StructDescr(name)
if w_fields is not space.w_None:
descr.define_fields(space, w_fields)
return descr
@@ -185,13 +183,15 @@
@unwrap_spec(name=str)
def getfield(self, space, name):
- w_ffitype, offset =
self.structdescr.get_type_and_offset_for_field(name)
+ w_ffitype, offset = self.structdescr.get_type_and_offset_for_field(
+ space, name)
field_getter = GetFieldConverter(space, self.rawmem, offset)
return field_getter.do_and_wrap(w_ffitype)
@unwrap_spec(name=str)
def setfield(self, space, name, w_value):
- w_ffitype, offset =
self.structdescr.get_type_and_offset_for_field(name)
+ w_ffitype, offset = self.structdescr.get_type_and_offset_for_field(
+ space, name)
field_setter = SetFieldConverter(space, self.rawmem, offset)
field_setter.unwrap_and_do(w_ffitype, w_value)
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,17 @@
types.void, FUNCFLAG_STDCALL)
sleep(10)
-
+ def test_by_ordinal(self):
+ if not self.iswin32:
+ skip("windows specific")
+ """
+ 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/module/_ffi/test/test_ztranslation.py
b/pypy/module/_ffi/test/test_ztranslation.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/_ffi/test/test_ztranslation.py
@@ -0,0 +1,4 @@
+from pypy.objspace.fake.checkmodule import checkmodule
+
+def test__ffi_translates():
+ checkmodule('_ffi', '_rawffi')
diff --git a/pypy/objspace/fake/checkmodule.py
b/pypy/objspace/fake/checkmodule.py
--- a/pypy/objspace/fake/checkmodule.py
+++ b/pypy/objspace/fake/checkmodule.py
@@ -2,13 +2,14 @@
from pypy.config.pypyoption import get_pypy_config
-def checkmodule(modname):
+def checkmodule(*modnames):
config = get_pypy_config(translating=True)
space = FakeObjSpace(config)
- mod = __import__('pypy.module.%s' % modname, None, None, ['__doc__'])
- # force computation and record what we wrap
- module = mod.Module(space, W_Root())
- for name in module.loaders:
- module._load_lazily(space, name)
+ for modname in modnames:
+ mod = __import__('pypy.module.%s' % modname, None, None, ['__doc__'])
+ # force computation and record what we wrap
+ module = mod.Module(space, W_Root())
+ for name in module.loaders:
+ module._load_lazily(space, name)
#
space.translates(**{'translation.list_comprehension_operations':True})
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,11 @@
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('by_ordinal', argtypes, restype,
+ dlsym_byordinal(self.lib, name),
+ flags=flags, keepalive=self)
def getaddressindll(self, name):
return dlsym(self.lib, name)
@@ -423,6 +428,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,36 @@
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
+
+ def test_by_ordinal2(self):
+ """
+ int __stdcall BBB_second_ordinal_function()
+ {
+ return 24;
+ }
+ """
+ from pypy.rlib.libffi import WinDLL
+ dll = WinDLL(self.libfoo_name)
+ f_by_name = dll.getpointer('BBB_second_ordinal_function' ,[],
+ types.uint)
+ f_by_ordinal = dll.getpointer_by_ordinal(2 ,[], types.uint)
+ print dir(f_by_name)
+ assert f_by_name.funcsym == f_by_ordinal.funcsym
+ chain = ArgChain()
+ assert 24 == f_by_ordinal.call(chain, lltype.Signed,
is_struct=False)
+
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit