gpt4 book ai didi

python - 如何使用 Cython 将 Python 列表传递给 C 函数

转载 作者:太空狗 更新时间:2023-10-29 15:40:39 25 4
gpt4 key购买 nike

我正在使用 Raspberry Pi 与连接到 GPIO 的自定义硬件进行交互。控制软件是用 Python 编写的,自定义硬件的接口(interface)是用 C 编写的,因为它是一个更快的 C 实现。我现在需要开始从我的 Python 调用我的 C 函数,并且最近一直在学习如何在 Cython 中包装 C。除了将 Python 列表传递给 C 函数外,我已准备好一切正常工作。

我的自定义硬件需要发送 1 到 32 个字节的任何地方,因此使用数组。

我在网上阅读的 Cython 教程和其他引用资料非常简单,不包括如何将列表传递给 C、如何使用我没有使用的 numpy,或者使用非常复杂的代码示例,这些示例对我来说缺乏足够的文档正确理解它。

我现在拥有的是:

测试.c

#include <stdio.h>
#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];
}

测试.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 = defns.getAll()
cdef bytes pyc = c
print pyc

定义.pxd

cdef extern from "test.h":
char a[4]
void pop()
void putAll(int n, char c[])
char *getAll()

使用 cython.org 上的教程,我的 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 中将它分开 - 但它非常难看。

此外,我不需要 Cython 来获得任何性能提升,除了使用 C 实现的库与我的自定义硬件接口(interface)与 Python 实现的硬件接口(interface)。

最佳答案

您可以将 Python 的 bytearray 与 Cython 一起使用,我认为它比 ctypes 更干净、更容易:

测试.py

larr = bytearray([4, 1, 2])
pyPutAll(3, larr)

这适用于您原来的 putAll C 函数:

测试.c

...
void putAll(int n, char c[]) {
memcpy(a, c, n);
}
...

pytest.pyx

# Pass python bytearray to C
def pyPutAll(int n, char[:] pyc):
defns.putAll(n, &pyc[0])

如果你需要传递一个列表,你必须在 pyx 函数中将它转换成一个 vector ,然后传递一个引用:

pytest.pyx

def pyPutAllList(int n, list pyc):
cdef vector[char] vec = pyc
defns.putAll(n, &vec[0])

关于python - 如何使用 Cython 将 Python 列表传递给 C 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28056597/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com