Message360013
@eryksun Sorry for the imprecision -- I was mixing what we do on Linux and Windows. A minimum verifiable example for Linux/MacOS would be
import ctypes
class bitstruct(ctypes.Structure):
_fields_ = [('addr', ctypes.c_long),
('rbit', ctypes.c_uint, 1),
('wbit', ctypes.c_uint, 1)]
def handler(args):
print("handler: ", args.addr, args.rbit, args.wbit)
callback = ctypes.CFUNCTYPE(None, bitstruct)(handler)
This works with 3.7.5 but raises a TypeError with 3.7.6.
For Windows (or, well, 64-bit Windows, the only kind we bother to support), we find that we have to wrap the function and use a POINTER to the struct, so what we really use is more like
import os, functools
def make_callback(args, func):
""" make callback function"""
@functools.wraps(func)
def wrapped(arg, **kwargs):
if hasattr(arg, 'contents'):
return func(arg.contents, **kwargs)
return func(arg, **kwargs)
if os.name =='nt': # also check for 64-bit
cb = ctypes.CFUNCTYPE(None, ctypes.POINTER(args))(wrapped)
else:
cb = ctypes.CFUNCTYPE(None, bitstruct)(handler)
return cb
callback = make_callback(bitstruct, handler)
> ...
> This seems rights to me. There is no problem passing a pointer
> as a function parameter.
The problem here is that code that worked with 3.7.5 raises a TypeError with 3.7.6.
I don't know that the solution we came up with is actually the best approach. I've asked for such guidance a few times now. I don't know why using a pointer would be required for a structure containing a "u_int, 1", but not for other structures, but any guidance would be much appreciated. |
|
Date |
User |
Action |
Args |
2020-01-14 23:40:54 | Matthew Newville | set | recipients:
+ Matthew Newville, vinay.sajip, eryksun, cheryl.sabella |
2020-01-14 23:40:54 | Matthew Newville | set | messageid: <1579045254.13.0.469822771246.issue39295@roundup.psfhosted.org> |
2020-01-14 23:40:54 | Matthew Newville | link | issue39295 messages |
2020-01-14 23:40:53 | Matthew Newville | create | |
|