【问题标题】:How to print the content of PyByteArrayObject*?如何打印 PyByteArrayObject* 的内容?
【发布时间】:2021-07-04 01:26:15
【问题描述】:

我正在使用PyArg_Parsetuple 解析从python 发送的带有Y 格式说明符的字节数组。

Y (bytearray) [PyByteArrayObject *]
Requires that the Python object is a bytearray object, without attempting any conversion. 
Raises TypeError if the object is not a bytearray object. 

在 C 代码中我正在做:

static PyObject* py_write(PyObject* self, PyObject* args)
{
       PyByteArrayObject* obj;
       PyArg_ParseTuple(args, "Y", &obj);

.
.
.

python 脚本正在发送以下数据:

arr = bytearray()
arr.append(0x2)
arr.append(0x0)

如何在 C 中遍历 PyByteArrayObject*?打印 2 和 0?

谢谢。

【问题讨论】:

  • 你看过PyByteArrayObject的声明了吗?
  • @AKX 谢谢找不到这个链接。希望现在能够这样做并回答我的问题。

标签: python c python-3.x


【解决方案1】:

你应该通过documented API而不是戳实现细节,特别是通过PyByteArray_AS_STRINGPyByteArray_AsString访问数据缓冲区而不是通过直接结构成员访问:

char *data = PyByteArray_AS_STRING(bytearray);
Py_ssize_t len = PyByteArray_GET_SIZE(bytearray);

for (Py_ssize_t i = 0; i < len; i++) {
    do_whatever_with(data[i]);
}

请注意,公共 API 中的所有内容都将字节数组作为 PyObject *,而不是 PyByteArrayObject *

【讨论】:

    【解决方案2】:

    在评论部分的帮助下,我找到了 PyByteArrayObject 的definition

    /* Object layout */
    typedef struct {
        PyObject_VAR_HEAD
        Py_ssize_t ob_alloc;   /* How many bytes allocated in ob_bytes */
        char *ob_bytes;        /* Physical backing buffer */
        char *ob_start;        /* Logical start inside ob_bytes */
        Py_ssize_t ob_exports; /* How many buffer exports */
    } PyByteArrayObject;
    

    以及要循环的实际代码

    PyByteArrayObject* obj;
    PyArg_ParseTuple(args, "Y", &obj);
    
    Py_ssize_t i = 0;
    for (i = 0; i < PyByteArray_GET_SIZE(obj); i++)
        printf("%u\n", obj->ob_bytes[i]);
    

    我得到了预期的输出。


    更好的是,只需使用Direct API

    char* s = PyByteArray_AsString(obj);
    int i = 0;
    for (i = 0; i < PyByteArray_GET_SIZE(obj); i++)
        printf("%u\n", s[i]);
    

    【讨论】:

    • 您正在那里戳实现细节 - 结构布局不是公共 API 的一部分。
    • @user2357112supportsMonica 然后我如何在 C 中打印从 python bytearray 传递的数据?
    猜你喜欢
    • 2019-08-29
    • 2014-06-04
    • 2020-09-08
    • 2020-04-13
    • 2020-08-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多