2016-12-04 6 views
0

Выполнение некоторых экспериментов с использованием python (средство python3) для подготовки данных (также как отправка их на провод - SPI) показывает, что он медленный (с ограниченной системой). Поэтому я думал о создании модуля расширения, написанного в C, чтобы отложить критическую работу. Я хотел бы также:Удлинительные модули: marshalling void * to bytearray (и/или наоборот)

  • сценарий python будет иметь доступ к блоку памяти, созданной malloc() в модуле расширения, мы надеемся, прозрачно, конвертируемых в bytearray
  • модуля расширения будет получить указатель на bytearray объект, созданный в python многообещающе прозрачно конвертируется в void *

цель состоит в том, чтобы иметь нулевую копию также в качестве блока памяти нулевого преобразования, доступной как python (как bytearray) и модуль расширения (как void *).

Есть ли способ, как этого достичь?

ответ

0

КИ, это кажется проще, чем ожидались ;-)

  • 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') 
>>>