Travis Oliphant schrieb:
> I've been playing a bit with ctypes and realized that with a little 
> help, it could be made much easier to interface with NumPy arrays.  
> Thus, I added a ctypes attribute to the NumPy array.  If ctypes is 
> installed, this attribute returns a "conversion" object otherwise an 
> AttributeError is raised.
> 
> The ctypes-conversion object has attributes which return c_types aware 
> objects so that the information can be passed directly to c-code (as an 
> integer, the number of dimensions can already be passed using c-types).
> 
> The information available and it's corresponding c_type is
> 
> data           -  c_void_p
> shape, strides -  c_int * nd  or c_long * nd or c_longlong * nd 
> depending on platform

I've also played a little, and I think one important limitation in ctypes
is that items in the argtypes list have to be ctypes types.  If that
limitation is removed (see the attached trivial patch) one can write a class
that implements 'from_param' and accepts ctypes arrays as well as numpy arrays
as argument in function calls (Maybe the _as_parameter_ stuff needs cleanup
as well).

The attached shape.py script implements this class, and has two examples.
The 'from_param' method checks the correct shape and itemtype of the arrays
that are passed as parameter.

Thomas
from ctypes import *

# typemap maps numpy typestrings to ctypes types
typemap = {}
for t in (c_byte, c_short, c_long, c_longlong):
    typemap["<i%s" % sizeof(t)] = t.__ctype_le__
    typemap[">i%s" % sizeof(t)] = t.__ctype_be__
for t in (c_ubyte, c_ushort, c_ulong, c_ulonglong):
    typemap["<u%s" % sizeof(t)] = t.__ctype_le__
    typemap[">u%s" % sizeof(t)] = t.__ctype_be__
for t in (c_float, c_double):
    typemap["<f%s" % sizeof(t)] = t.__ctype_le__
    typemap[">f%s" % sizeof(t)] = t.__ctype_be__

class ArrayType(object):
    """An adapter class.  Instances can be used in foreign functions'
    argtypes list.  They allow to pass numpy arrays as function
    parameters if the shape and itemtype matches.
    """
    def __init__(self, ctype, shape):
        self.shape = shape
        self.itemtype = ctype
        for dim in shape[::-1]:
            ctype = ctype * dim
        self.arraytype = ctype

    def from_param(self, obj):
        # accept native ctypes array instances.
        if isinstance(obj, self.arraytype):
            return obj
        # accept objects which have the correct __array_shape__ and
        # __array_typestr__ attributes.
        if self.shape != obj.__array_shape__:
            raise ValueError, "shape mismatch: %s instead of %s" % \
                  (self.shape, obj.__array_shape__)
        if typemap[obj.__array_typestr__] != self.itemtype:
            raise ValueError, "itemtype mismatch: %s instead of %s" % \
                  (typemap[obj.__array_typestr__], self.itemtype)
        # we should probably check also other things...
        # Return a void pointer to the data
        addr = int(obj.__array_data__[0], 16)
        return c_void_p(addr)

################################################################

import numpy
import sys
import ctypes.util

if sys.platform == "win32":
    libc = cdll.msvcr71
else:
    libc = CDLL(ctypes.util.find_library("c"))

libc.printf.argtypes = c_char_p, ArrayType(c_long, (2, 3))
libc.printf("%p\n", numpy.array([[1, 2, 3], [4, 5, 6]]))

libc.printf.argtypes = c_char_p, ArrayType(c_long, (32000,))
libc.printf("%p\n", numpy.zeros(32000))
Index: _ctypes.c
===================================================================
RCS file: /cvsroot/ctypes/ctypes/source/_ctypes.c,v
retrieving revision 1.340
diff -u -r1.340 _ctypes.c
--- _ctypes.c   22 Jun 2006 19:21:28 -0000      1.340
+++ _ctypes.c   4 Jul 2006 09:56:06 -0000
@@ -1633,9 +1633,8 @@
 
        for (i = 0; i < nArgs; ++i) {
                PyObject *tp = PyTuple_GET_ITEM(ob, i);
-               StgDictObject *dict = PyType_stgdict(tp);
                PyObject *cnv = PyObject_GetAttrString(tp, "from_param");
-               if (!dict || !cnv)
+               if (!cnv)
                        goto argtypes_error_1;
                PyTuple_SET_ITEM(converters, i, cnv);
        }
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
Numpy-discussion mailing list
Numpy-discussion@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/numpy-discussion

Reply via email to