【问题标题】:Pass C string to python (ctypes)将 C 字符串传递给 python (ctypes)
【发布时间】:2021-04-27 18:46:29
【问题描述】:

我正在尝试通过 ctypes 将我的 C 代码中的 char * 和 char ** 传递给 Python。这是我的代码:

.h

int process(unsigned char *line, unsigned char (*word)[128], char *(chunk)[16]);

.c 文件

unsigned char line[256];
unsigned char word[266][128];
char chunk[128][16];

fprintf(stdout, " output_value: %d, %s, %s", process(line, word, chunk), word[0], chunk[0]);

.py

fin = open(filename, encoding='UTF-8')
content = fin.read().splitlines()

_process = _mod.process
_process.argtypes = [ POINTER(c_ubyte), POINTER(c_char_p), POINTER(c_char_p) ]
_process.restype = c_int

string_org = ''.join(map(str, content)).encode("UTF-8")
line = (c_ubyte * len(string_org)).from_buffer_copy(string_org)

word = (c_char_p)()
chunk = (c_char_p)()

print("output_value: %d %s %s" %(process(line, word, chunk), word[0], chunk[0]))

结果:

TypeError: 'c_char_p' object is not subscriptable --> print("output_value: %d %s %s" %(process(line, word, chunk), word[0], chunk[0]))
Segmentation fault (core dumped)

是什么导致了这个问题?

是和一些内存管理有关还是只是获取C字符串的方法不对?

谁能回答我的问题。提前谢谢你。

【问题讨论】:

    标签: python c string ctypes


    【解决方案1】:

    word = c_char_p() 在 C 中创建一个等效于 char* word = 0 的指针实例。它是一个空指针,因此调用 process 函数会取消对空指针的引用并崩溃。

    POINTER(c_char_p) 是与 C 中的 char** 等效的类型,它不在您的函数签名中。

    下面是功能 DLL 代码,用于写入您想要的类型,但我假设 char *(chunk)[16] 是一个错字,而您真的想要 char (*chunk)[16]

    test.c

    #include <stdio.h>
    #include <string.h>
    
    __declspec(dllexport)
    int process(char *line, char (*word)[128], char (*chunk)[16]) {
        printf("%s\n",line);
        strcpy_s(word[0],128,"hello");
        strcpy_s(word[1],128,"world");
        strcpy_s(chunk[0],16,"one");
        strcpy_s(chunk[1],16,"two");
        return 2;
    }
    

    test.py

    from ctypes import *
    
    # type declarations
    dll = CDLL('./test')
    dll.process.argtypes = c_char_p,POINTER(c_char * 128),POINTER(c_char * 16)
    dll.process.restype = c_int
    
    word = (c_char * 128 * 2)()   # equivalent to C char word[2][128]
    chunk = (c_char * 16 * 2)()   # equivalent to C char chunk[2][16]
    
    ret = dll.process(b"some line", word, chunk)
    print(f'{ret} {word[0].value} {word[1].value} {chunk[0].value} {chunk[1].value}')
    

    输出:

    some line
    2 b'hello' b'world' b'one' b'two'
    

    为了阅读您的文件,如果我正确地解释了您的代码,您希望读取整个文件并删除换行符以形成一个长行。由于该文件最初预计为 UTF-8,您可以跳过解码/编码,只需执行以下操作:

    with open(filename,'rb') as f:
        line = f.read().replace(b'\n',b' ')
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-07-08
      • 2015-02-12
      • 2017-04-21
      • 2020-08-01
      • 2017-06-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多