How this C function was called through ctypes this way?
jfong at ms4.hinet.net
jfong at ms4.hinet.net
Thu Feb 4 04:33:02 EST 2016
Here is an example from "Python Cookbook, Third Edition(by David Beazley and Brian K. Jones)" Chapter 15.1. "Accessing C Code Using ctypes"
-------------------
import ctypes
...
# Try to locate the .so file in the same directory as this file
...
_mod = ctypes.cdll.LoadLibrary(_path)
...
...
# void avg(double *, int n)
# Define a special type for the 'double *' argument
class DoubleArrayType:
def from_param(self, param):
typename = type(param).__name__
if hasattr(self, 'from_' + typename):
return getattr(self, 'from_' + typename)(param)
elif isinstance(param, ctypes.Array):
return param
else:
raise TypeError("Can't convert %s" % typename)
...
# Cast from array.array objects
def from_array(self, param):
...
...
# Cast from lists
def from_list(self, param):
val = ((ctypes.c_double)*len(param))(*param)
return val
# Cast from a numpy array
def from_ndarray(self, param):
...
...
DoubleArray = DoubleArrayType()
_avg = _mod.avg
_avg.argtypes = (DoubleArray, ctypes.c_int)
_avg.restype = ctypes.c_double
def avg(values):
return _avg(values, len(values))
avg([1,2,3])
------------------
The followings was quoted from the book which explain how it does:
"The DoubleArrayType class shows how to handle this situation. In this class, a single method from_param() is defined. The role of this method is to take a single parameter and narrow it down to a compatible ctypes object (a pointer to a ctypes.c_double, in the example). Within from_param(), you are free to do anything that you wish. In the solution, the typename of the parameter is extracted and used to dispatch to a more specialized method. For example, if a list is passed, the typename is list and a method from_list() is invoked."
What confuse me are:
(1) at line: _avg.argtypes = (DoubleArray, ctypes.c_int)
The "DoubleArry" is an instance of the class "DoubleArrayType", Can it appear at where a type was expected?
(2) How the method "from_param" was invoked? I can't see any mechanism to reach it from the "_avg(values, len(values))" call.
Best Regards,
Jach Fong
More information about the Python-list
mailing list