如何将字符串从 Python3 传递给 cythonized C++ 函数

Posted

技术标签:

【中文标题】如何将字符串从 Python3 传递给 cythonized C++ 函数【英文标题】:How to pass string from Python3 to cythonized C++ function 【发布时间】:2017-07-29 11:03:01 【问题描述】:

我试图了解如何在 Python3 和 cythonized C++ 函数之间传递字符串值。但是我无法使用 Cython 构建库。

特别不明白source.pyx中如何声明字符串返回值和字符串参数。使用 int 类型它可以正常工作。

我在使用 clang 构建过程中遇到的错误如下:

candidate function not viable: no known conversion from 'PyObject *' (aka '_object *') to 'char *' for 1st argument

我的source.pyx 如下:

cdef extern from "source.cpp":
  cdef str fun(str param)

def pyfun(mystring):
  return fun(mystring)

我的source.cpp 是:

char * fun(char *string) 
  return string;

【问题讨论】:

您了解文档的这一部分吗? cython.readthedocs.io/en/latest/src/tutorial/…。我还在努力。 谢谢。实际上,我设法在此表 cython.readthedocs.io/en/latest/src/userguide/… 后面传递了字符串。我认为您建议使用libcpp.stringstd::string 是否比将bytes 传递给char* 然后将返回值(类型为bytes)转换为str 更好? 我链接的文档页面似乎对C char 字符串的评价很低,特别是因为Py3 使用unicode。但最好的方法可能取决于您对 C++ 中的字符串所做的操作。 事实上,我正在连接旧的遗留代码,而我对 cython 的经验仍然很少。如果您可以使用libcpp.string 作为答案,我可以接受它。 【参考方案1】:

除了原始代码中的错误之外,我设法使其与以下source.pyx 一起工作(Python3 中的bytes 类型和C++ 中的char* 之间的转换):

cdef extern from "source.cpp":
  cdef char* fun(char* param)

def pyfun(mystring):
  mystring_b = mystring.encode('utf-8')
  rvalue = fun(mystring_b).decode('utf-8')
  return rvalue

如果内存是在fun 中使用malloc 分配的,它也需要被释放,否则会出现内存泄漏(使用C 指针时,总是值得考虑谁拥有内存)。这样做的修改版本是:

from libc.stdlib cimport free

# cdef extern as before

def pyfun(mystring):
    cdef char* value_from_fun
    mystring_b = mystring.encode('utf-8')
    value_from_fun = fun(mystring_b)
    try:    
        return value_from_fun.decode('utf-8')
    finally:
        free(value_from_fun)

类型转换的作用与以前相同。


编辑

根据hpaulj 在原始问题中的评论,这里是带有libcpp.string 的版本,它映射了<string> 中定义的C++ std::string

from libcpp.string cimport string

cdef extern from "source.cpp":
  cdef string fun(string param)

def pyfun(mystring):
  mystring_ = mystring.encode('utf-8')
  rvalue = fun(mystring_).decode('utf-8')
  return rvalue

【讨论】:

fun 返回的内存是使用malloc 分配的吗?如果是,那么您可能还需要释放它。如果没有,那应该没问题。 在这种特殊情况下不是,但它可能有用。我该怎么做?随意修改答案。 我已经编辑了你会怎么做。如果您想以不同的方式构造它,那么也可以随意更改它

以上是关于如何将字符串从 Python3 传递给 cythonized C++ 函数的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Python 3 中使用 stdin 将字符串传递给 subprocess.run

如何将命令行参数从pytest传递给代码

python3嵌套字典解包格式字符串

如何将字符串从 NSMutableArray 传递给 double

如何将字符串中的加号从视图传递给控制器​​?

在python运行时将数据从GUI传递给线程