使用Cython扩展NumPy

4
我正在尝试封装一个具有许多此类函数的头文件 test.h
void test(int N, int* data_in, int* data_out);

所以我可以使用numpy中的那些。
目前我有以下Cython代码:
test.pyx
import numpy as np
cimport numpy as np

ctypedef np.int_t itype_t

cdef extern from 'VolumeForm.h':
    void _test 'test' (int, int*, int*)

def wrap_test(np.ndarray[itype_t, ndim=2] data):
    cdef np.ndarray[dtype_t, ndim=1] out
    out = np.zeros((data.shape[0],1), dtype=np.double)
    _test(
        data.shape[0],
        <itype_t*> data.data,
        <itype_t*> out.data
    )
    return out

然而,当我尝试编译它时,出现了错误:


Error converting Pyrex file to C:
(...)
Cannot assign type 'test.itype_t *' to 'int *'

这句话的英译中是:“我该如何修复这个问题?”
2个回答

4

这个问题目前正在Cython邮件列表上讨论;显然,它源于Cython库中的一个小错误:

http://codespeak.net/mailman/listinfo/cython-dev

目前,一个潜在的解决方法是使用dtype为np.long的NumPy数组,然后写上'ctypedef np.long_t itype_t'。这样,你只需要用long int来取代int使C代码能够正常运行。


2

另一个无需将变量从int更改为long的解决方法:在cdef extern from '...'块中更改函数签名。 Cython仅在生成.c文件时使用cdef extern块中的声明来检查类型,但生成的C代码只是执行#include "VolumeForm.h",因此您可以得到所需结果。

import numpy as np
cimport numpy as np

ctypedef np.int_t itype_t

cdef extern from 'VolumeForm.h':
    # NOTE: We changed the int* declarations to itype_t*
    void _test 'test' (int, itype_t*, itype_t*)

def wrap_test(np.ndarray[itype_t, ndim=2] data):
    cdef np.ndarray[dtype_t, ndim=1] out
    out = np.zeros((data.shape[0],1), dtype=np.double)
    _test(
        data.shape[0],
        <itype_t*> data.data,
        <itype_t*> out.data
    )
    return out

Cython不会对上述内容提出任何异议。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接