繁体   English   中英

Cython - 将字符串列表转换为字符 **

[英]Cython - converting list of strings to char **

如何将 python 字符串的 python 列表转换为以空char**结尾的char**以便将其传递给外部 C 函数?

我有:

struct saferun_task:
    saferun_jail   *jail
    saferun_limits *limits

    char **argv
    int stdin_fd  
    int stdout_fd
    int stderr_fd

int saferun_run(saferun_inst *inst, saferun_task *task, saferun_stat *stat)

在 cdef 外部块中

我想将诸如('./a.out', 'param1', 'param2')为可以分配给saferun_task.argv

如何?

从Cython文档:

char* PyString_AsString (PyObject *string)

返回字符串内容的以null结尾的表示形式。 指针指的是字符串的内部缓冲区,而不是副本。 不得以任何方式修改数据。 不得取消分配。

我没有Cython编译器设置和方便的atm(我可以稍后运行并检查)但是,这应该导致代码看起来像:

from libc.stdlib cimport malloc, free

cdef char **string_buf = malloc(len(pystr_list) * sizeof(char*))

for i in range(len(pystr_list)):
    string_buf[i] = PyString_AsString(pystr_list[i])

# Do stuff with string_buf as a char**
# ...

free(string_buf)

指针stringBuf现在是原始数据的char **而不复制任何字符串 - 尽管您不应该编辑每个字符串中的数据,因为字符串应该被视为const char *(来自docs)。 如果你需要操作字符串,你必须记忆数据或制作你不关心在Python中丢弃的新对象 - 尽管你有一个字符串元组我怀疑你是在编辑它们。

Python 有权以任何非标准格式保留字符串的内部表示。 因此,您必须先将字符串转换为字节,例如使用.encode('utf-8')或任何其他编码格式。

在你有可用的字节后,你可以通过将字节分配给char *变量来轻松地将它们转换为指针,在 Cython 代码中只需执行以下操作:

s = 'abc'
b = s.encode('utf-8') + b'\x00'
cdef const char * ptr = b

请注意,在上面的代码中,我将b'\\x00'附加到字节,因为字节表示不必在末尾包含零字节,而 C/C++ 在接受char *字符串时需要该零字节。

同样,如果 C/C++ 代码返回char *那么您可以轻松地将其转换回字符串,如下所示:

cdef const char * ptr = .... # This pointer is filled-in by C code
b = <bytes>ptr
s = s.decode('utf-8') # Now it contains string

在上面的代码中,注意通过<bytes>ptrchar *到 bytes 的转换。 Cython 通过搜索第一个零字节并将字符串截断到它来将char *转换为字节,最终字节将不包含零字节。

现在您还可以创建一个char **数组以将其传递给 C/C++,如下面的代码所示。 我假设您正在编译 64 位二进制文​​件(带有 64 位指针):

# Imports
import numpy as np
cimport numpy as np
cimport cython
from libc.stdint cimport *

# Cython func
def cython_func():
    ss = ['ab', 'cde', 'f']
    bs = [e.encode('utf-8') + b'\x00' for e in ss]
    a = np.zeros(len(bs), dtype = np.uint64)
    for i in range(len(bs)):
        a[i] = <uint64_t>(<char *>bs[i])

    cdef uint64_t[:] ca = a
    cdef char ** final_ptr = <char **>&ca[0]

    with nogil:
        some_c_func(final_ptr)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM