【发布时间】:2018-03-16 10:26:08
【问题描述】:
我正在尝试将字符串列表传递给 C++ 函数,该函数使用 Cython 将 char** 作为参数。
我尝试了其他我不记得的解决方案,但我主要尝试了以下两个选项:
-
使用从here提取的转换函数,这与here的答案基本相同,但在
g++编译时会引发错误cy_wrapper.cpp: In function 'char** _pyx_f_10cy_wrapper_to_cstring_array(PyObject*)': cy_wrapper.cpp:1223:44: error 'PyString_AsString' was not declared in this scope __pyx_t_5 = PyString_AsString(__pyx_t_4); if (unlikely(__pyx_t_5 == ((char *)NULL)) -
使用python字符串的编码方法,正如here中所建议的那样,但答案并不令人满意,因为它会引发错误:
cy_wrapper.pyx:14:35: Storing unsafe C derivative of temporary Python reference
我查看了~/.local/lib/python3.5/site-packages/Cython/Includes/cpython 的库文件,并找到了包含我需要的函数PyString_AsString 的文件string.pxd。
为什么找不到?如果没有可能使用它,是否有解决方法?
我正在使用 arm64 架构上的 Ubuntu 16.04.4 LTS(tegra 内核)。
我的cy_wrapper.pyx是这样的:
from cpython.string cimport PyString_AsString
from libc.stdlib cimport malloc
cdef extern:
cdef cppclass imageNet:
imageNet* Create(int argc, char** argv)
cdef char** to_cstring_array(list_str):
cdef char** ret = <char **>malloc(len(list_str) * sizeof(char *))
for i in range(len(list_str)):
ret[i] = PyString_AsString(list_str[i])
return ret
cdef class PyImageNet:
cdef imageNet* c_net
def Create(self, argc, kwargs):
cdef char** c_argv = to_cstring_array(kwargs)
return PyImageNetFactory(self.c_net.Create(argc, c_argv))
cdef object PyImageNetFactory(imageNet* ptr):
cdef PyImageNet py_obj = PyImageNet()
py_obj.c_net = ptr
return py_obj
我的setup.py:
from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
setup(
cmdclass = {"build_ext": build_ext},
ext_modules = [
Extension("cy_wrapper",
sources=["cy_wrapper.pyx"],
libraries=["shared_inference"],
language="c++",
extra_compile_args=["-O3", "-Wall"],
extra_link_args=["-L../build/"]
)
]
)
Ofc libshared_inference.so 位于../build/ 并定义类imageNet。
【问题讨论】:
-
问题是
PyString_AsString是python2的功能,python3中不存在。 Cython 文档在这里涵盖了这个主题:cython.readthedocs.io/en/latest/src/tutorial/… -
这里还隐藏着一个内存管理灾难(因为“存储临时 Python 引用的不安全 C 派生”是在警告你)。在这两种情况下,内存都归 Python 字符串所有,因此内存只有在 Python 对象有效时才有效。
标签: python python-3.x type-conversion cython wrapper