簡體   English   中英

擴展模塊:將void *編組為字節數組(反之亦然)

[英]Extension modules: marshalling void * to bytearray (and/or vice versa)

使用python (意味着python3 )進行一些實驗來准備數據(也將它們發送到SPI),這表明它很慢(系統有限)。 因此,我正在考慮創建用C編寫的擴展模塊,以延遲關鍵的工作。 我想要:

  • python腳本將有權訪問由擴展模塊中的malloc()創建的內存塊,希望可以透明地轉換為bytearray
  • 擴展模塊將獲得指向在python創建的bytearray對象的指針,希望可以透明地轉換為void *

目標是將零拷貝作為零轉換存儲塊,也可以由python (作為bytearray )和擴展模塊(作為void * )訪問。

有什么方法,如何實現呢?

好的,這似乎比預期的要簡單;-)

  • bytearray為訪問底層內存塊提供了直接支持,這正是需要的
  • 有一個用於從函數調用參數列表中提取bytearray對象的格式說明符

C擴展模塊[ test.c ]:

#include <Python.h>
#include <stdint.h>

/* Forward prototype declaration */
static PyObject *transform(PyObject *self, PyObject *args);

/* Methods exported by this extension module */
static PyMethodDef test_methods[] =
{
     {"transform", transform, METH_VARARGS, "testing buffer transformation"},
     {NULL, NULL, 0, NULL}
};


/* Extension module definition */
static struct PyModuleDef test_module =
{
   PyModuleDef_HEAD_INIT,
   "BytearrayTest",
   NULL,
   -1,
   test_methods,
};


/* 
 * The test function 
 */
static PyObject *transform(PyObject *self, PyObject *args)
{
    PyByteArrayObject *byte_array;
    uint8_t           *buff;
    int                buff_len = 0;
    int                i;


    /* Get the bytearray object */
    if (!PyArg_ParseTuple(args, "Y", &byte_array))
        return NULL;

    buff     = (uint8_t *)(byte_array->ob_bytes); /* data   */
    buff_len = byte_array->ob_alloc;              /* length */

    /* Perform desired transformation */
    for (i = 0; i < buff_len; ++i)
        buff[i] += 65;

    /* Return void */
    Py_INCREF(Py_None);
    return Py_None;
}


/* Mandatory extension module init function */
PyMODINIT_FUNC PyInit_BytearrayTest(void)
{
    return PyModule_Create(&test_module);
}

C擴展模塊的構建/部署腳本[ setup.py ]:

#!/usr/bin/python3
from distutils.core import setup, Extension

module = Extension('BytearrayTest', sources = ['test.c'])

setup (name = 'BytearrayTest',
       version = '1.0',
       description = 'This is a bytearray test package',
       ext_modules = [module])

構建/安裝擴展模塊:

# ./setup.py build
# ./setup.py install

測試一下:

>>> import BytearrayTest
>>> a = bytearray(16); a
bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
>>> BytearrayTest.transform(a); a
bytearray(b'AAAAAAAAAAAAAAAA')
>>>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM