The following script (based on an extract of test_callbacks.py)
demonstrates the problem. When run on a Sparc-based Solaris 10
platform, the output shows correct operation only when the c_longdouble
arguments appear first in the function call -- the use of other types
would seem to throw off argument alignment.
Could this be an issue with libffi?
#!/bin/env python
import sys
from ctypes import *
class Callback:
functype = CFUNCTYPE
def callback(self, *args):
self.got_args = args
return args[-1]
def check_type(self, typ, arg):
print "typ=%s" % (typ,)
print "Trying (typ) ..."
PROTO = self.functype.im_func(typ, typ)
result = PROTO(self.callback)(arg)
print " %s result=%s; got_args=%r" % ("*FAILED*" if result !=
3.14 else "WORKED", result, self.got_args)
print "Trying (c_byte, typ) ..."
PROTO = self.functype.im_func(typ, c_byte, typ)
result = PROTO(self.callback)(-3, arg)
print " %s result=%s; got_args=%r" % ("*FAILED*" if result !=
3.14 else "WORKED", result, self.got_args)
print "Trying (typ, c_byte) ..."
PROTO = self.functype.im_func(typ, typ, c_byte)
result = PROTO(self.callback)(arg, -3)
print " %s result=%s; got_args=%r" % ("*FAILED*" if result !=
3.14 else "WORKED", result, self.got_args)
print "Trying (c_byte, typ, typ) ..."
PROTO = self.functype.im_func(typ, c_byte, typ, typ)
result = PROTO(self.callback)(-3, arg, arg)
print " %s result=%s; got_args=%r" % ("*FAILED*" if result !=
3.14 else "WORKED", result, self.got_args)
print "Trying (typ, typ) ..."
PROTO = self.functype.im_func(typ, typ, typ)
result = PROTO(self.callback)(arg, arg)
print " %s result=%s; got_args=%r" % ("*FAILED*" if result !=
3.14 else "WORKED", result, self.got_args)
print "Trying (c_double, typ) ..."
PROTO = self.functype.im_func(typ, c_double, typ)
result = PROTO(self.callback)(arg, arg)
print " %s result=%s; got_args=%r" % ("*FAILED*" if result !=
3.14 else "WORKED", result, self.got_args)
print "trying (c_int, typ) ..."
PROTO = self.functype.im_func(typ, c_int, typ)
result = PROTO(self.callback)(-3, arg)
print " %s result=%s; got_args=%r" % ("*FAILED*" if result !=
3.14 else "WORKED", result, self.got_args)
print "trying (c_long, typ) ..."
PROTO = self.functype.im_func(typ, c_long, typ)
result = PROTO(self.callback)(-3, arg)
print " %s result=%s; got_args=%r" % ("*FAILED*" if result !=
3.14 else "WORKED", result, self.got_args)
print "trying (c_longlong, typ) ..."
PROTO = self.functype.im_func(typ, c_longlong, typ)
result = PROTO(self.callback)(-3, arg)
print " %s result=%s; got_args=%r" % ("*FAILED*" if result !=
3.14 else "WORKED", result, self.got_args)
callback = Callback()
callback.check_type(c_longdouble, 3.14)
# callback.check_type(c_longdouble, -3.14)
> ./python ~/tryLongDouble.py
typ=<class 'ctypes.c_longdouble'>
Trying (typ) ...
WORKED result=3.14; got_args=(3.1400000000000001,)
Trying (c_byte, typ) ...
*FAILED* result=0.0; got_args=(-3, 0.0)
Trying (typ, c_byte) ...
*FAILED* result=-3.0; got_args=(3.1400000000000001, -3)
Trying (c_byte, typ, typ) ...
*FAILED* result=-inf; got_args=(-3, nan, -inf)
Trying (typ, typ) ...
WORKED result=3.14; got_args=(3.1400000000000001, 3.1400000000000001)
Trying (c_double, typ) ...
*FAILED* result=0.0; got_args=(3.1400000000000001, 0.0)
trying (c_int, typ) ...
*FAILED* result=0.0; got_args=(-3, 0.0)
trying (c_long, typ) ...
*FAILED* result=0.0; got_args=(-3, 0.0)
trying (c_longlong, typ) ...
*FAILED* result=0.0; got_args=(-3, 0.0) |