-----Original Message-----
From: eryk sun [mailto:[email protected]]
from_param is a hook method for a type that's set in a function pointer's
argtypes. It gets called to convert an argument when the function pointer is
called from Python. The return value can be a ctypes instance, an object with a
hard-coded conversion (e.g. a string or integer), or an object that defines an
_as_parameter_ attribute.
Only ctypes types are supported in callbacks, which unfortunately isn't
documented clearly. Specifically, the class dict needs to be an extended C
storage dict (i.e. StgDictObject), either to look up the getfunc of a simple
type or to ensure that instantiating a non-simple type returns a ctypes
instance (i.e. CDataObject) with a known size.
The relevant code in _CallPythonObject is as follows (when stripped of
declarations and error handling):
cnv = PySequence_GetItem(converters, i);
dict = PyType_stgdict(cnv);
if (dict && dict->getfunc && !_ctypes_simple_instance(cnv)) {
v = dict->getfunc(*pArgs, dict->size);
PyTuple_SET_ITEM(arglist, i, v);
} else if (dict) {
obj = (CDataObject *)PyObject_CallFunctionObjArgs(cnv, NULL);
memcpy(obj->b_ptr, *pArgs, dict->size);
PyTuple_SET_ITEM(arglist, i, (PyObject *)obj);
} else {
PyErr_SetString(PyExc_TypeError,
"cannot build parameter");
I don't have much experience with SWIG. Does it provide some means to
instantiate a wrapped type from an address? If it does, then you can use a void
pointer as the callback parameter.
Hi Eryk,
Thanks for looking at this. I had got as far as looking at the code above and
guessed that only ctypes types were supported. This does seem like a bit of a
functionality gap that cannot be solved easily by users of ctypes. It would
appear to be fairly easy to define a protocol for objects that can be
instantiated from ctypes arguments before passing to Python callables, i.e.
some requirement for a class method factory that takes a ctypes type as a
parameter and returns a Python object. This would seem to be a natural
complement to from_param()/_as_parameter_ for the C/C++ to Python direction of
function calls.
I had started with an implementation that converted a c_void_p value and
instantiated the required SWIG Python wrapper. This is not too difficult as
SWIG allows its types to be extended in both the C/C++ world and the Python
world. The result is only a one liner for each callback parameter but it is
still ugly as the writer of the callback has to know what type the argument is
and remember to call the "constructor" before accessing the attributes of the
object.
My requirement is to wrap an API for testers and customers to write simple test
cases and any ugliness in the test cases is undesirable given that the users
will probably not be Python experts and maybe not even developers.
Regards
Bill.
--
https://mail.python.org/mailman/listinfo/python-list