我正在尝试编写一个包含一些 c 和一些 python 部分的模块。我正在使用 cython 来弥补差距。
我想在 python 中存储我的(很长的)字符串常量,因为它有更好的语法:
const char long_string = "\npart of string\n"
"next part\n"
"last part\n";
versus:
long_string = """
part of string
next part
last part
"""
(字符串比这个长得多,而且更复杂 - 以至于我不想添加和删除"
s and \n"
每次我想用语法突出显示来编辑它时。事实上,它们是 openCL 内核。)
我需要能够使用 cython 将它们转换为 C 字符串,并根据文档 http://docs.cython.org/src/tutorial/strings.html我应该只需要这个:
cdef bytes py_bytes = py_string.encode()
cdef char* c_string = py_bytes
并且无需手动内存管理,c_string
只要我保留引用就会起作用py_bytes
.
但是,我无法通过简单的 printf 测试来实现这一点。这是我的 cython 文件:
cdef extern from "stdio.h":
printf(char* string)
def go():
py_string = """
a complicated string
with a few
newlines.
"""
cdef bytes py_bytes = py_string.encode()
cdef char* c_string = py_bytes
printf(c_string)
print "we don't get this far :("
当在运行时编译时使用pyximport
在出现段错误之前,向终端提供以下输出:
a complicated string
with a few
newlines.
Segmentation fault: 11
现在,我已经检查了 cython 在 c 文件中实际放入的内容,并在普通 C 文件中尝试了它doesn't段错误:
#include "stdio.h"
static char __pyx_k_1[] = "\na complicated string\nwith a few\nnewlines.\n";
int main(void) {
void* output = printf(__pyx_k_1);
if (!output) {
printf("apparently, !output.");
}
}
需要明确的是,cython 生成的代码捕获以下输出printf
并测试“不是那样”。变量的类型是PyObject*
.
我唯一的猜测是字符串未正确终止,因此 printf 只是继续超出它的末尾并导致段错误,但由于这在我的纯 c 测试中不会发生,所以我完全被难住了。
所以,我真正的问题是我该如何really将 c 字符串从 cython 传递给 c 代码?非常欢迎指出解决我试图在顶部解决的实际问题的更简单方法的答案:)