python往c语⾔传指针_如何使⽤Cython将Python列表传递给C
函数
我正在使⽤Raspberry Pi与连接到GPIO的⾃定义硬件进⾏交互.控制软件是⽤
Python编写的,⾃定义硬件的接⼝是⽤C语⾔编写的,因为它是⼀个更快的C实现.我现在需要从我的Python开始调⽤我的C函数,并且最近⼀直在学习如何在Cython中包装C.除了将Python列表传递给C函数之外,我已经完成了所有⼯作.
我的⾃定义硬件需要从1到32个字节发送,因此使⽤数组.
我在线阅读的Cython教程和其他参考⽂献都⾮常简单,不包括如何将列表传递给C,使⽤numpy,我没有使⽤,或使⽤⾮常复杂的代码⽰例,缺乏⾜够的⽂档供我理解正常.
我现在拥有的是:
test.c的
#include
#include "test.h"
void pop(void) {
a[0] = 0x55;
a[1] = 0x66;
a[2] = 0x77;
a[3] = '\0';
}
void putAll(int n, char c[]) {
memcpy(a, c, n);
}
char *getAll(void) {
return &a[0];
}
test.h
char a[4];
void putAll(int n, char[]);
char *getAll(void);
pytest.pyx
cimport defns
# Populate C array with values
def pypop():
defns.pop()
# Pass python list to C
def pyPutAll(int n, char[:] pyc):
cdef char* c = pyc
defns.putAll(n, c)
# Get array from C
def pyGetAll():
cdef char* c = All()
cdef bytes pyc = c
print pyc
defns.pxd
cdef extern from "test.h":
char a[4]
void pop()
void putAll(int n, char c[])
char *getAll()
使⽤中的教程,我的getAll()和pop()函数可以⼯作,但是当我包含putAll()函数时(取⾃在链接中到的process_byte_data⽰例代码,在Unicode下传递字符串>从Python代码接受字符串) ),我收到此错误:
python setup.py build_ext -i
Error compiling Cython file:
------------------------------------------------------------
...
def pyputAll(int n, char[:] pyc):
^
------------------------------------------------------------
pytest.pyx:13:25: Expected an identifier or literal
现在,我有办法解决这个问题 – 将最多32个字节组合成⼀个int并传递为⼀个long int,然后在C中将它拉开 – 但它⾮常难看.
此外,除了使⽤C实现的库与我的⾃定义硬件与Python实现的硬件接⼝之外,我不需要Cython来获得任何性能提升.
任何帮助将不胜感激.
(编辑)解决⽅案
我设法让这个⼯作.以下是我现在为需要它的⼈提供的代码.
pytest.pyx
...
def pyPutAll(int n, c):
cdef int *ptr
ptr = malloc(n*cython.sizeof(int))
if ptr is NULL:
raise MemoryError()
for i in xrange(n):
ptr[i] = c[i]
自定义函数怎么用c语言
defns.putAll(n, ptr)
free(ptr)
...
test.c的
void putAll(int n, int c[])
{
char d[n];
int i;
for (i=0;i
d[i] = c[i];
}
memcpy(addr, d, n);
}
这段代码不是最优的,因为它在python / cython代码中使⽤了int,然后在C函数中将它转换为char. pytest.pyc中的pyPutAll()函数接受⼀个普通的python列表.然后它创建⼀个C指针并分配内存.迭代列表,将每个值放⼊C数组,最后将指针传递给C函数.
它完成了⼯作,但我确信其他⼈可以提供更有效的解决⽅案.
马特

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。