如何在 cython 中调用此函数?

Posted

技术标签:

【中文标题】如何在 cython 中调用此函数?【英文标题】:how can I call this function in cython? 【发布时间】:2012-01-10 01:03:06 【问题描述】:

在 cython 中仅使用 numpy 调用此函数的最佳方法是什么? 我不会使用 ctypes、memcpy、malloc 等。

功能 1)

#include <stdio.h>
extern "C" void cfun(const void * indatav, int rowcount, int colcount,
void * outdatav);

void cfun(const void * indatav, int rowcount, int colcount, void *
outdatav) 
    //void cfun(const double * indata, int rowcount, int colcount,
double * outdata) 
    const double * indata = (double *) indatav;
    double * outdata = (double *) outdatav;
    int i;
    puts("Here we go!");
    for (i = 0; i < rowcount * colcount; ++i) 
        outdata[i] = indata[i] * 4;
    
    puts("Done!");

功能 2)

#include <stdio.h>

extern "C" __declspec(dllexport) void cfun(const double ** indata, int
rowcount, int colcount, double ** outdata) 
    for (int i = 0; i < rowcount; ++i) 
        for (int j = 0; j < colcount; ++j) 
            outdata[i][j] = indata[i][j] * 4;
        
    

崔元俊

【问题讨论】:

不需要从 python 调用这些函数。你可以使用 numpy 做同样的事情 我必须这样做的原因是我需要包装一些现有的 c、c++ 库.. 所以.. 只是制作 numpy 函数不是解决方案。这就是为什么我发布了像上面这样的简单示例。 然后发布真正的功能,发布您的代码尝试和您遇到的错误 【参考方案1】:

您可以直接从 Cython 中“调用”该函数,方法是将其声明为 extern

cdef extern from "mylibraryheader.h":
    void cfun1(void* indatav, int rowcount, int colcount, void* outdatav)
    void cfun2(double** indata, int rowcount, int colcount, doubke** outdata)

您现在可以像在 C/C++ 中一样调用这些函数。请注意,Cython 中没有 const 关键字,您可以将其省略。不幸的是,我不能给你一个如何将 NumPy 数组转换为 double 数组的例子。但这里有一个从双打列表中运行它的示例。

cdef extern from "mylibraryheader.h":
    void cfun1(void* indatav, int rowcount, int colcount, void* outdatav)
    void cfun2(double** indata, int rowcount, int colcount, double** outdata)

cdef extern from "stdlib.h":
    ctypedef int size_t
    void* malloc(size_t)
    void free(void*)

def py_cfunc1(*values):
    cdef int i = 0
    cdef int size = sizeof(double)*len(values)
    cdef double* indatav = <double*> malloc(size)
    cdef double* outdatav = <double*> malloc(size)
    cdef list outvalues = []
    for v in values:
        indatav[i] = <double>v
        i += 1
    cfun1(<void*>indatav, 1, len(values), <void*>outdatav)
    for 0 <= i < len(values):
        outvalues.append(outdatav[i])
    return outvalues

注意:未经测试

【讨论】:

【参考方案2】:

您不能从 cython 调用这个函数 - 你必须将它作为一个 cython 函数 - here 是一些很好的例子。作为参考,功能1):

cimport numpy as np

def cfun(np.ndarray indata, int rowcount, int colcount, np.ndarray outdata):
    cdef int i
    print("Here we go!")
    for i in range(rowcount * colcount):
        outdata[i] = indata[i] * 4
    print("Done!")

如果你真的想调用它,你将不得不使用 ctypes 或编写你自己的包装器。使用swig 也可以。

【讨论】:

你能给我做一个函数 2) 的例子吗?

以上是关于如何在 cython 中调用此函数?的主要内容,如果未能解决你的问题,请参考以下文章

Cython:如何在没有 GIL 的情况下打印

如何正确地将 numpy 数组传递给 Cython 函数?

包装采用 char** [in/out] 的 C 函数调用,以在 cython 中返回 python 列表

无法将 cpplist 导入 Cython?

Cython __pyx_r 可能在此函数中未初始化使用

如何使用 cython 将 python 类公开给 c++