是否可以在python中定义c型变量并将其地址传递给cython包装的函数

时间:2019-05-29 15:53:43

标签: python c cython

我正在用Cython包装一个C库,现在我不知道如何解决从python将地址传递给C函数的方法。详细信息如下:

我有一些C函数,该函数将某些预先定义的C变量作为地址并更改其值:

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

作为C用户,我可以通过以下方式使用此功能:

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

执行后,var1var2都等于5。现在,我想用cython包装c_func。我想从包装器中导入py_func并使用它,但是我不知道如何从python定义c变量。

我已经做过的事情(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对象,但是用python包装的C函数不应与之冲突。

有可能吗?

1 个答案:

答案 0 :(得分:1)

我不知道您的示例在实践中如何有意义,但是一种可能的方法是将由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])