【问题标题】:Receiving non Null-Terminated data in Python Ctypes callback在 Python Ctypes 回调中接收非空终止数据
【发布时间】:2012-01-27 17:11:11
【问题描述】:

我正在为 DLL 编写 Python ctypes 包装器。

当事件发生时,DLL 会尝试使用以下原型调用回调函数:

void Function(u8 *Data, u16 Length)

本质上,它为我们提供了一个指向原始数据缓冲区的指针,以及该缓冲区的长度。

我正在尝试在我的 python 代码中找到一种接收和处理这些数据的方法。

如果我将 ctypes 函数类型声明为 char 指针:

TX_CALLBACK_FUNC_TYPE = CFUNCTYPE(None, c_char_p, c_int)

然后数据被视为以空字符结尾的字符串,如果缓冲区中存在任何 0x00 字节,我将得到截断的数据。

如果我将 ctypes 函数类型声明为 void 指针:

TX_CALLBACK_FUNC_TYPE = CFUNCTYPE(None, c_void_p, c_int)

然后我得到一个长整数值,我假设它是原始数据的地址 - 但我不知道如何检索数据以在 Python 中使用它。

如果我将 ctypes 函数类型声明为指向 char 的指针:

TX_CALLBACK_FUNC_TYPE = CFUNCTYPE(None, POINTER(char), c_int)

然后我得到一个 ctypes.LP_c_char 对象,但我不知道如何访问对象中的原始数据。

在 Python 中访问从包装的 DLL 返回的原始数据的最佳方法是什么?

【问题讨论】:

    标签: python ctypes


    【解决方案1】:

    你需要一个缓冲区:

    >>> import ctypes
    >>> b = ctypes.c_buffer("abc\0def", 16)
    >>> b.value
    'abc'
    >>> b.raw
    'abc\x00def\x00\x00\x00\x00\x00\x00\x00\x00\x00'
    

    【讨论】:

    • 感谢您对此的帮助。我使用的是缓冲区,但我错误地使用了 .value 而不是 .raw。
    • 另请注意,c_buffer 似乎已被弃用,取而代之的是 create_string_buffer。
    【解决方案2】:

    要从ctypes.LP_c_char 中获取数据,只需对其进行切片

    def processBytes(pBuffer,len):<br>
       <b>print(pBuffer[:len])</b>
    
    
    CB_FUNC_TYPE = ctypes.CFUNCTION(None, ctypes.POINTER(ctypes.c_char),ctypes.c_int)<br>
    cb_func = CB_FUNC_TYPE(processBytes)
    
    
    //Need to setup cb_func in C <br>
    //In C assign your call-back function<br>
    void (*c_cb_func)(char *, int) = cb_func<br>
    
    // Call your python function from C<br>
    (c_cb_func)(pBuffer,len)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-11-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多