Можно ли определить переменную c-типа в Python и передать ее адрес в завернутую функцию Cython? - PullRequest
0 голосов
/ 29 мая 2019

Я обертываю C-библиотеку с помощью Cython, и пока я не знаю, как обойти передачу адреса функции C из Python. Подробности ниже:

У меня есть некоторая C-функция, которая принимает адрес некоторой заранее определенной переменной C и меняет ее значение:

void c_func(int* x) {
*x=5;
}

Как пользователь C, я могу использовать эту функцию следующим образом:

def int var1
def int var2
c_func(&var1)
c_func(&var2)

После выполнения оба значения var1 и var2 будут равны 5. Теперь я хочу обернуть c_func с помощью Cython. Я хотел бы иметь py_func, который можно импортировать из пакета-обертки и использовать, но я не знаю, как определить переменные c из python.

Что я уже сделал (в jupyter):

%load_ext cython

%%cython

cdef int some_int

cdef extern from *:
    """
    void c_func(int* x) {
    *x=5;
    }

    """
    int c_func(int* x)

c_func(&some_int)

print(some_int)

Что я хочу получить:

%%cython

# This part should be in separate pyx file
cdef extern from *:
    """
    void c_func(int* x) {
    *x=5;
    }

    """
    int c_func(int* x)

def py_func(var):
    c_func(&var)

# The following part is user API
from wrapper import py_func

var_to_pass_in_py_func = ... # somehow defined C variable

py_func(var_to_pass_in_py_func) 

print(var_to_pass_in_py_func) # should print 5

var_to_pass_in_py_func не может быть преобразован в объект python, но функции C, заключенные в python, не должны конфликтовать с ним.

Возможно ли это?

1 Ответ

1 голос
/ 30 мая 2019

Я понятия не имею, как ваш пример имеет смысл на практике, но один из возможных способов - передать буфер, которым управляет python, в функцию C. Например:

%%cython -a -f 

# Suppose this is the external C function needed to wrap
cdef void c_func(int* value_to_change):
    value_to_change[0] = 123;

def py_func(int[:] buffer_to_change):
    c_func(&buffer_to_change[0]);

from array import array
from ctypes import *

a = array('i', [0]);
py_func(a)
print(a[0])

b = (c_int*1)() # c_int array with length 1
py_func(b)
print(b[0])
...