Author: Matti Picus <[email protected]>
Branch: win_ffi
Changeset: r55256:3dbd7782528b
Date: 2012-06-01 16:25 +0300
http://bitbucket.org/pypy/pypy/changeset/3dbd7782528b/
Log: test, add WinDLL in _ffi
diff --git a/pypy/module/_ffi/__init__.py b/pypy/module/_ffi/__init__.py
--- a/pypy/module/_ffi/__init__.py
+++ b/pypy/module/_ffi/__init__.py
@@ -1,4 +1,5 @@
from pypy.interpreter.mixedmodule import MixedModule
+import os
class Module(MixedModule):
@@ -10,7 +11,8 @@
'_StructDescr': 'interp_struct.W__StructDescr',
'Field': 'interp_struct.W_Field',
}
-
+ if os.name == 'nt':
+ interpleveldefs['WinDLL'] = 'interp_funcptr.W_WinDLL'
appleveldefs = {
'Structure': 'app_struct.Structure',
}
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
@@ -9,6 +9,7 @@
#
from pypy.rlib import jit
from pypy.rlib import libffi
+from pypy.rlib.clibffi import get_libc_name, StackCheckError
from pypy.rlib.rdynload import DLOpenError
from pypy.rlib.rarithmetic import intmask, r_uint
from pypy.rlib.objectmodel import we_are_translated
@@ -59,7 +60,10 @@
self = jit.promote(self)
argchain = self.build_argchain(space, args_w)
func_caller = CallFunctionConverter(space, self.func, argchain)
- return func_caller.do_and_wrap(self.w_restype)
+ try:
+ return func_caller.do_and_wrap(self.w_restype)
+ except StackCheckError, e:
+ raise OperationError(space.w_ValueError, space.wrap(e.message))
#return self._do_call(space, argchain)
def free_temp_buffers(self, space):
@@ -254,6 +258,7 @@
class W_CDLL(Wrappable):
def __init__(self, space, name, mode):
+ self.flags = libffi.FUNCFLAG_CDECL
self.space = space
if name is None:
self.name = "<None>"
@@ -271,7 +276,8 @@
w_argtypes,
w_restype)
try:
- func = self.cdll.getpointer(name, argtypes, restype)
+ 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)
@@ -300,10 +306,26 @@
getaddressindll = interp2app(W_CDLL.getaddressindll),
)
+class W_WinDLL(W_CDLL):
+ def __init__(self, space, name, mode):
+ W_CDLL.__init__(self, space, name, mode)
+ self.flags = libffi.FUNCFLAG_STDCALL
+
+@unwrap_spec(name='str_or_None', mode=int)
+def descr_new_windll(space, w_type, name, mode=-1):
+ return space.wrap(W_WinDLL(space, name, mode))
+
+
+W_WinDLL.typedef = TypeDef(
+ '_ffi.WinDLL',
+ __new__ = interp2app(descr_new_windll),
+ getfunc = interp2app(W_WinDLL.getfunc),
+ getaddressindll = interp2app(W_WinDLL.getaddressindll),
+ )
+
# ========================================================================
def get_libc(space):
- from pypy.rlib.clibffi import get_libc_name
try:
return space.wrap(W_CDLL(space, get_libc_name(), -1))
except OSError, e:
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
@@ -93,7 +93,7 @@
def test_getaddressindll(self):
import sys
- from _ffi import CDLL, types
+ from _ffi import CDLL
libm = CDLL(self.libm_name)
pow_addr = libm.getaddressindll('pow')
fff = sys.maxint*2-1
@@ -102,7 +102,6 @@
assert pow_addr == self.pow_addr & fff
def test_func_fromaddr(self):
- import sys
from _ffi import CDLL, types, FuncPtr
libm = CDLL(self.libm_name)
pow_addr = libm.getaddressindll('pow')
@@ -566,3 +565,37 @@
skip("unix specific")
libnone = CDLL(None)
raises(AttributeError, "libnone.getfunc('I_do_not_exist', [],
types.void)")
+
+ def test_calling_convention1(self):
+ if not self.iswin32:
+ skip("windows specific")
+ from _ffi import WinDLL, types
+ libm = WinDLL(self.libm_name)
+ pow = libm.getfunc('pow', [types.double, types.double], types.double)
+ try:
+ pow(2, 3)
+ except ValueError, e:
+ assert e.message.startswith('Procedure called with')
+ else:
+ assert 0, 'test must assert, wrong calling convention'
+
+ def test_calling_convention2(self):
+ if not self.iswin32:
+ skip("windows specific")
+ from _ffi import WinDLL, types
+ kernel = WinDLL('Kernel32.dll')
+ sleep = kernel.getfunc('Sleep', [types.uint], types.void)
+ sleep(10)
+
+ def test_calling_convention3(self):
+ if not self.iswin32:
+ skip("windows specific")
+ from _ffi import CDLL, types
+ wrong_kernel = CDLL('Kernel32.dll')
+ wrong_sleep = wrong_kernel.getfunc('Sleep', [types.uint], types.void)
+ try:
+ wrong_sleep(10)
+ except ValueError, e:
+ assert e.message.startswith('Procedure called with')
+ else:
+ assert 0, 'test must assert, wrong calling convention'
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit