如何在ctypes中生成字符数组并将其指针作为函数参数传递

我想使用 C++ 中包含在 Python 字符列表中的序列化缓冲区中的一些信息,使用 ctypes。我尝试了以下方法,但我不明白为什么我的参数类型会引发错误。


我有一些 C++ 代码的 C 包装器,形式为


extern "C" {

    special_object *special_object_new() { return new special_object(); }


    int function(special_object *O, int buffer_size, char *buffer) {

        char *buf = (char*) malloc(buffer_size);

        for(int i = 0; i < buffer_size; i++) buf[i] = buffer[i];

        O->do_something_in_cpp_with_buf(buf);

        free(buf);

        buf = NULL;

        return 0;

    }

}

我想从 Python ctypes传递function一个字符缓冲区buf。这个字符缓冲区最初作为字符列表出现在 Python 中,所以我首先使用


import ctypes

import cdll

buf_c = (ctypes.c_char*len(buf))(*buf)

然后使用


buf_p = ctypes.cast(buf_c, ctypes.POINTER(ctypes.c_char))

它有一个类型


>>> <class 'ctypes.LP_c_char'>

我已经知道这个缓冲区的大小buf_size,作为一个整数。


我执行以下(加载库和声明函数参数),


lib = cdll.LoadLibrary('PATH_TO_LIB/lib.so')

lib.function.restype = ctypes.c_int

lib.function.argtypes = [ctypes.c_int, ctypes.POINTER(ctypes.c_char)]

然后我创建包含函数的类,


class Special(object):

    def __init__(self):

        self.obj = lib.special_object_new()


    def py_function(self, buffer_size, buffer):

        res = lib.function(self.obj, buffer_size, buffer)

最后,我尝试调用它,因为


s = Special()

s.py_function(ctypes.c_int(buf_size), buffer)

但我得到了错误


ArgumentError: argument 1: <type 'exceptions.TypeError'>: wrong type

当我制作指针时,我无法弄清楚我做错了什么?任何帮助,将不胜感激!


慕尼黑8549860
浏览 166回答 1
1回答

慕妹3146593

您必须为每个函数定义所有参数。这是一个工作示例:测试.cpp#ifdef _WIN32#&nbsp; &nbsp;define API __declspec(dllexport)#else#&nbsp; &nbsp;define API#endif#include <stdio.h>struct special_object {&nbsp; &nbsp; special_object() {&nbsp; &nbsp; &nbsp; &nbsp; printf("created\n");&nbsp; &nbsp; }&nbsp; &nbsp; ~special_object() {&nbsp; &nbsp; &nbsp; &nbsp; printf("destroyed\n");&nbsp; &nbsp; }&nbsp; &nbsp; void print(char* buffer, int buffer_size) {&nbsp; &nbsp; &nbsp; &nbsp; for(int i = 0; i < buffer_size; i++)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; printf("%02X ",static_cast<unsigned char>(buffer[i]));&nbsp; &nbsp; &nbsp; &nbsp; printf("\n");&nbsp; &nbsp; }};extern "C" {&nbsp; &nbsp; API special_object *special_object_new() {&nbsp; &nbsp; &nbsp; &nbsp; return new special_object();&nbsp; &nbsp; }&nbsp; &nbsp; API void special_object_print(special_object *O, char *buffer, int buffer_size) {&nbsp; &nbsp; &nbsp; &nbsp; O->print(buffer, buffer_size);&nbsp; &nbsp; }&nbsp; &nbsp; API void special_object_delete(special_object *O) {&nbsp; &nbsp; &nbsp; &nbsp; delete O;&nbsp; &nbsp; }}测试文件from ctypes import *lib = CDLL('test')lib.special_object_new.argtypes = ()lib.special_object_new.restype = c_void_plib.special_object_print.argtypes = c_void_p, c_char_p, c_intlib.special_object_print.restype = Nonelib.special_object_delete.argtypes = c_void_p,lib.special_object_delete.restype = Noneclass Special:&nbsp; &nbsp; def __init__(self):&nbsp; &nbsp; &nbsp; &nbsp; self.obj = lib.special_object_new()&nbsp; &nbsp; def __del__(self):&nbsp; &nbsp; &nbsp; &nbsp; lib.special_object_delete(self.obj)&nbsp; &nbsp; def print(self,buffer):&nbsp; &nbsp; &nbsp; &nbsp; lib.special_object_print(self.obj,buffer,len(buffer))s = Special()s.print(bytes([0x01,0x02,0xaa,0x55]))s.print(b'hello, world!')输出:created01 02 AA 5568 65 6C 6C 6F 2C 20 77 6F 72 6C 64 21destroyed
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python