为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

慕尼黑8549860 2021-10-26 15:56:52
我想使用 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 ctypesimport cdllbuf_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_intlib.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当我制作指针时,我无法弄清楚我做错了什么?任何帮助,将不胜感激!
查看完整描述

1 回答

?
慕妹3146593

TA贡献1820条经验 获得超9个赞

您必须为每个函数定义所有参数。这是一个工作示例:


测试.cpp


#ifdef _WIN32

#   define API __declspec(dllexport)

#else

#   define API

#endif


#include <stdio.h>


struct special_object {

    special_object() {

        printf("created\n");

    }


    ~special_object() {

        printf("destroyed\n");

    }


    void print(char* buffer, int buffer_size) {

        for(int i = 0; i < buffer_size; i++)

            printf("%02X ",static_cast<unsigned char>(buffer[i]));

        printf("\n");

    }

};


extern "C" {

    API special_object *special_object_new() {

        return new special_object();

    }


    API void special_object_print(special_object *O, char *buffer, int buffer_size) {

        O->print(buffer, buffer_size);

    }


    API void special_object_delete(special_object *O) {

        delete O;

    }

}

测试文件


from ctypes import *


lib = CDLL('test')

lib.special_object_new.argtypes = ()

lib.special_object_new.restype = c_void_p

lib.special_object_print.argtypes = c_void_p, c_char_p, c_int

lib.special_object_print.restype = None

lib.special_object_delete.argtypes = c_void_p,

lib.special_object_delete.restype = None


class Special:

    def __init__(self):

        self.obj = lib.special_object_new()

    def __del__(self):

        lib.special_object_delete(self.obj)

    def print(self,buffer):

        lib.special_object_print(self.obj,buffer,len(buffer))


s = Special()

s.print(bytes([0x01,0x02,0xaa,0x55]))

s.print(b'hello, world!')

输出:


created

01 02 AA 55

68 65 6C 6C 6F 2C 20 77 6F 72 6C 64 21

destroyed


查看完整回答
反对 回复 2021-10-26
  • 1 回答
  • 0 关注
  • 154 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信