Как я могу вызвать эту функцию в Cython? - PullRequest
5 голосов
/ 10 января 2012

Каков наилучший способ вызвать эту функцию в Cython только с numpy?Я не собираюсь использовать ctypes, memcpy, malloc и т.д ..

function 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!");
}

function 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;
        }
    }
}

Wonjun, Choi

Ответы [ 2 ]

2 голосов
/ 24 января 2012

Вы можете 'вызвать' функцию непосредственно из 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

Примечание: не проверено

0 голосов
/ 10 января 2012

Вы не можете вызвать эту функцию из Cython - вам нужно написать как функцию Cython - некоторые хорошие примеры здесь . Для справки: функция 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 также будет работать.

...