Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/303.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Cython with Python3.5:将字符串列表转换为字符**_Python_Python 3.x_Type Conversion_Cython_Wrapper - Fatal编程技术网

Cython with Python3.5:将字符串列表转换为字符**

Cython with Python3.5:将字符串列表转换为字符**,python,python-3.x,type-conversion,cython,wrapper,Python,Python 3.x,Type Conversion,Cython,Wrapper,我试图把字符串列表传递给C++函数,它使用Cython作为char **。 我尝试了其他解决方案,但我记不得了,但我主要尝试了以下两种方案: 在g++编译中使用从中提取的转换函数,这与答案基本相同,但会引发一个错误 cy_wrapper.cpp: In function 'char** _pyx_f_10cy_wrapper_to_cstring_array(PyObject*)': cy_wrapper.cpp:1223:44: error 'PyString_AsString' was no

我试图把字符串列表传递给C++函数,它使用Cython作为char **。 我尝试了其他解决方案,但我记不得了,但我主要尝试了以下两种方案:

  • 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字符串的编码方法,如中所建议,但答案并不令人满意,因为它会引发错误:

    cy_wrapper.pyx:14:35: Storing unsafe C derivative of temporary Python reference
    
  • 我在
    ~/.local/lib/python3.5/site packages/Cython/Includes/cpython
    的库文件中找到了包含我需要的函数
    PyString\u的文件
    string.pxd

    为什么找不到?如果不可能使用它,是否有解决方法

    我正在arm64 arch上开发Ubuntu16.04.4LTS(tegra内核)

    我的
    cy\u wrapper.pyx
    与此完全相同:

    来自cpython.string cimport PyString\u AsString
    来自libc.stdlib cimport malloc
    cdef外部人员:
    cdef cppclass imageNet:
    imageNet*创建(整数argc,字符**argv)
    cdef字符**到数组(列表):
    cdef char**ret=malloc(len(list_str)*sizeof(char*))
    对于范围内的i(len(list_str)):
    ret[i]=PyString\u AsString(list\u str[i])
    回程网
    cdef类PyImageNet:
    cdef图像网*c_网
    def创建(自身、argc、kwargs):
    cdef字符**c_argv=到_cstring_数组(kwargs)
    返回PyImageNetFactory(self.c_net.Create(argc,c_argv))
    cdef对象PyImageNetFactory(imageNet*ptr):
    cdef PyImageNet py_obj=PyImageNet()
    py_obj.c_net=ptr
    返回py_obj
    
    My
    setup.py

    来自distutils.core导入设置
    从distutils.extension导入扩展
    从Cython.Distutils导入生成\u ext
    设置(
    cmdclass={“build\u ext”:build\u ext},
    外部模块=[
    扩展(“cy_包装器”,
    sources=[“cy_wrapper.pyx”],
    库=[“共享推理”],
    language=“c++”,
    额外参数=[“-O3”,“-Wall”],
    额外链接参数=[“-L../build/”]
    )
    ]
    )
    

    Ofc
    libshared\u推断。因此,
    位于
    ./build/
    中,并定义了类
    imageNet

    ,对于那些感兴趣的人,下面是我如何将我的
    字符串列表
    转换为
    字符**
    (我忘了在问题中提到我的方法是静态的,但对于我的解决方案来说这并不重要),希望这能帮助别人

    # cy_wrapper.pyx
    from libc.stdlib cimport malloc, free
    
    cdef extern:
        cdef cppclass imageNet:
            @staticmethod
            imageNet* Create(int argc, char** argv)
    
    cdef class PyImageNet:
        cdef imageNet* c_net
        @staticmethod
        def Create(args):
            # Declare char**
            cdef char** c_argv
            # Allocate memory
            c_argv = <char**>malloc(len(args) * sizeof(char*))
            # Check if allocation went fine
            if c_argv is NULL:
                raise MemoryError()
            # Convert str to char* and store it into our char**
            for i in range(len(args)):
                args[i] = args[i].encode()
                c_argv[i] = args[i]
            # Grabbing return value
            cdef imageNet* c_tmp_net = imageNet.Create(len(args), c_argv)
            # Let him go
            free(c_argv)
            # Return python-compatible value
            return PyImageNetFactory(c_tmp_net)
    
    cdef object PyImageNetFactory(imageNet* ptr):
        cdef PyImageNet py_obj = PyImageNet()
        py_obj.c_net = ptr
        return py_obj
    

    问题在于,
    PyString\u AsString
    是python2的功能,而python3中没有。Cython文档在这里介绍了这个主题:这里还隐藏了一个内存管理灾难(正如“存储临时Python引用的不安全C派生代码”警告您的那样)。在这两种情况下,内存都属于Python字符串,因此只有Python对象有效时,内存才有效。
    # test.py
    import cy_wrapper
    args = ["str1", "str2"]
    net = cy_wrapper.PyImageNet.Create(args)