C&C++   发布时间:2022-04-03  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了将数组从c传输到python大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在将一个双数组从c函数传递给 python函数.我的代码是:
C代码

double *compute(int size,const double a[])
{
    double* array;
    array = malloc(sizeof(doublE)*sizE);
    for (int i=0; i<size; i++)
    {
    arraY[i] = 3*a[i];
    }
    //printf("Array in compute-function is: \n[");
    //for(int i = 0; i < size; i++)
        //printf("%f,",arraY[i]);
    //printf("]\n");
    return array;
}

PYX代码

cdef class ArrayWrapper:
    cdef void* data_ptr
    cdef int size

    cdef set_data(self,int size,void* data_ptr):
        """ Set the data of the array
        This cAnnot be done in the constructor as it must recieve C-level
        arguments.
        Parameters:
        -----------
        size: int
            Length of the array.
        data_ptr: void*
            Pointer to the data            
        """
        self.data_ptr = data_ptr
        self.size = size

    def __array__(self):
        """ Here we use the __array__ method,that is called when numpy
            tries to get an array from the object."""
        cdef np.npy_intp shape[1]
        shape[0] = <np.npy_intp> self.size
        # Create a 1D array,of length 'size'
        ndarray = np.pyArray_SimpleNewFromData(1,shape,np.NPY_INT,self.data_ptr)
        return ndarray

    def __dealloc__(self):
        """ Frees the array. This is called by Python when all the
        references to the object are gone. """
        free(<void*>self.data_ptr)


def py_compute(int size,np.ndarray[np.double_t,ndim=1] a):
    """ Python binding of the 'compute' function in 'GNLSE_RHs.c' that does
        not copy the data allocated in C.
    """
    cdef double *array
    cdef np.ndarray ndarray
    # Call the C function
    array = compute(size,<double*> a.data)

    array_wrapper = ArrayWrapper()
    array_wrapper.set_data(size,<void*> array) 
    ndarray = np.array(array_wrapper,copy=falsE)
    # Assign our object to the 'base' of the ndarray object
    ndarray.base = <PyObject*> array_wrapper
    # Increment the reference count,as the above assignement was done in
    # C,and Python does not kNow that there is this additional reference
    Py_INCREF(array_wrapper)


    return ndarray

Python代码

for i in xrange(10):
    x[i] = i;

a = cython_wrapper.py_compute(10,X)
print a

但我的结果是

[         0          0          0 1074266112          0 1075314688          0 1075970048          0 1076363264]

而不是预期的

[  0.   3.   6.   9.  12.  15.  18.  21.  24.  27.]

我的错误在哪里?我认为它与有问题的指针传输有关,但我不确定.

解决方法

这里的错误是在线

ndarray = np.pyArray_SimpleNewFromData(1,self.data_ptr)

你告诉numpy self.data_ptr指向一个int数组而不是一个双精度数.

您可以通过告诉numpy正确的数据类型来修复代码,如下所示:

ndarray = np.pyArray_SimpleNewFromData(1,np.NPY_DOUBLE,self.data_ptr)

它应该按预期工作.

除此之外,您可以稍微简化您的包装器代码,而不必传入输入数组的大小,因为它已经包含在您传递给py_compute的np.ndarray

def py_compute(np.ndarray[np.double_t,ndim=1] a):
    """ Python binding of the 'compute' function in 'GNLSE_RHs.c' that does
        not copy the data allocated in C.
    """
    cdef double *array
    cdef np.ndarray ndarray
    cdef size = a.shape[0]

    # Call the C function
    array = compute(size,&a[0])

    array_wrapper = ArrayWrapper()
    array_wrapper.set_data(size,and Python does not kNow that there is this additional reference
    Py_INCREF(array_wrapper)


    return ndarray

大佬总结

以上是大佬教程为你收集整理的将数组从c传输到python全部内容,希望文章能够帮你解决将数组从c传输到python所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。