使用cython包装现有C库时,定义numpy数组的数据类型

时间:2012-08-17 15:00:25

标签: python numpy cython

我是cython的新手,当我需要在包装现有的C库(foolib)时为我的numpy数组定义一个类型时,我有点迷失了。该库根据平台使用int大小的已定义类型,如果它是以32位或64位构建的。

以下是foolib.h的一段摘录:

#include "footypes.h"
...
int foo_zone_read(int fn, int B, int Z, char *zonename, foosize_t *size);

以下是footypes.h

中的内容
# if FOO_BUILD_64BIT
# define FOO_SIZEOF_SIZE    64
   typedef long foosize_t;
# else
#  define FOO_SIZEOF_SIZE    32
   typedef int foosize_t;
# endif

我也有cython包装器。这是cython标题foolib.pxd

cdef extern from "foolib.h":
    ctypedef int foosize_t
    ...
    int foo_zone_read(int fn, int B, int Z, char *zonename, foosize_t *size)

实际的cython包装器bar.pyx

import numpy
cimport numpy
cimport foolib
...
cdef class pyFOO(object):

   def __init__(self, filename)
        pass

    cpdef zone_read(self, int B, int Z):
        cdef char zonename[MAXNAMELENGTH]
        cdef int *zsize
        cdef int ztype_read
        cdef numpy.ndarray[cgsize_t, ndim=1] azsize

在最后一行,当我尝试编译时出现cython错误:

cdef numpy.ndarray[cgsize_t, ndim=1] azsize
                          ^    
------------------------------------------------------------

bar.pyx:285:31: Invalid type.

我试着阅读C-API numpy引用,但我有点迷失了。我想要的只是输入正确类型的asize。我知道在Linux上它将是dtype=int32dtype=int64,具体取决于foolib的编译。如果我会像这样创建数组:asize=numpy.ones(2, dtype=numpy.int64)它会起作用,但现在类型是硬编码的,我不希望这样。

所以我的问题是如何通过以某种方式在footypes.h和numpy数组之间传递信息来获得正确的类型。 我的第二个问题是我如何指定我的numpy数组的大小(如果我在python语法中这样做很容易,但是使用numpy C-API对我来说并不清楚)。我知道它可以是shape(2)或(6)的数组,具体取决于运行时条件。

提前致谢。

0 个答案:

没有答案