Доступ к указателям void в Python (с помощью SWIG или чего-то еще)

StackOverflow https://stackoverflow.com/questions/2345354

  •  23-09-2019
  •  | 
  •  

Вопрос

Я пытался использовать SWIG для обертывания простой библиотеки, которая использует ioctl() для заполнения структуры, подобной следующей:

struct data
{
  header* hdr;
  void* data;
  size_t len;
};

данные является указателем на буфер, лен это длина этого буфера.

Я не могу понять, как преобразовать данные в строку Python (или массив).Кроме того, мне нужен способ освободить этот буфер в деструкторе.Любые предложения приветствуются.

Это было полезно?

Решение

Поскольку вы говорите "или что-то еще" в названии вопроса - если вы решите использовать типы данных, вы можете представлять собой void* с c_void_p (один из ctypes' основные типы данных, и получить доступ к таким функциям , как free и memcpy из библиотеки времени выполнения C (при условии, что последняя доступна как динамическая библиотека DLL / .so, но в наши дни это довольно распространено).Чтобы получить изменяемый символьный буфер, в который вы можете memcpy данные, используемые create_string_buffer создать строку_буфера.

Конечно, вы могли бы в качестве альтернативы использовать Python C API -- PyByteArray_FromStringAndSize PyByteArray_FromStringAndSize это то, что вы бы использовали в этом случае, чтобы скопировать массив байтов из вашего void* и длина (и, конечно, вы бы назвали free напрямую, когда это уместно, поскольку в любом случае это всего лишь C-код).

Еще одна возможность, которую следует рассмотреть, - это Китон, Python-подобный язык, предназначенный для написания расширений Python и такой, что компилятор Cython может генерировать компилируемый код C из исходных текстов Cython - в Cython ваш struct было бы:

cdef struct data:
    void* hdr
    void* data
    unsigned int* len

предполагая, что вы не хотите утруждать себя объявлением header (то есть, что только data и len это важно для вас здесь) -- size_t, я полагаю, на данный момент не является частью Cython (я могу ошибаться, они продолжают добавлять материал;-), но unsigned int наверное, смогу.

Извините, прошло слишком много времени с тех пор, как я использовал SWIG всерьез (со всеми этими превосходными альтернативами) - я бы пропустил Q, если бы не это заманчивое предложение "или что-то еще" в названии;-).

Другие советы

swig предоставляет модуль с именем 'cdata.i'.Вы должны включить это в файл определения интерфейса.

Как только вы включаете это, оно предоставляет две функции cdata() и memmove().Учитывая значение void * и длину двоичных данных, cdata() преобразует их в строковый тип целевого языка.memmove() - это наоборот.учитывая строковый тип, он скопирует содержимое строки (включая встроенные нулевые байты) в тип C void*.

С этим модулем обработка двоичных данных становится намного проще.Я надеюсь, что это то, что вам нужно.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top