我正在尝试编写一个带有一些c和一些python部分的模块。 我正在使用cython弥补差距。
我想在python中存储我的(非常长的)字符串常量,因为它的语法更好:
const char long_string = "npart of stringn" "next partn" "last partn";
与:
long_string = """ part of string next part last part """
(字符串比这长得多,而且更复杂 – 我不想每次想要用语法高亮来编辑它时都要添加和删除"
s和n"
。事实上,它们是openCL内核。)
我需要能够使用cython将它们变成c字符串,根据文档我应该只需要:
cdef bytes py_bytes = py_string.encode() cdef char* c_string = py_bytes
并且没有手动内存管理,只要我保留对py_bytes
的引用, c_string
就会起作用。
但是,我无法通过简单的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
编译时,在segfaulting之前向终端提供以下输出:
a complicated string with a few newlines. Segmentation fault: 11
现在,我已经检查了cython实际放入c文件中的内容,并在一个不会发生段错误的vanilla C文件中尝试过:
#include "stdio.h" static char __pyx_k_1[] = "na complicated stringnwith a fewnnewlines.n"; int main(void) { void* output = printf(__pyx_k_1); if (!output) { printf("apparently, !output."); } }
要清楚,cython会生成捕获printf
输出的代码并测试“not that”。 变量的类型是PyObject*
。
我唯一的猜测是,字符串被不正确地终止,所以printf只是继续它的结尾并导致段错误,但是因为在我的纯c测试中没有发生,所以我完全被难倒了。
所以,我的实际问题是如何真正将c-string传递给cython中的c代码? 答案指出一个更容易的方法来解决我试图在顶部解决的实际问题也非常欢迎:)
从libc.stdio
导入printf
为我解决了这个问题:
from libc.stdio cimport printf 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 actually got this far! :)"
错误发生在printf
的声明中。 那应该是,正如stdio.pxd
列出的那样,
cdef extern from *: ctypedef char const_char "const char" int printf(const_char *, ...)
而你的版本是隐式object printf(char *)
; 默认的返回值类型是Python对象,而不是C中的int
。获得正确的声明会关闭Cython尝试从printf
返回值的Py_XDECREF
。
(顺便说一下,在你的“vanilla”C问题中,你不应该将printf
的返回值转换为void *
。)
以上就是c/c++开发分享通过cython将python字符串传递给C语言相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/c-cdevelopment/562338.html