Soy muy nuevo en swig y estoy intentando crear una envoltura de swig para usar algunos archivos C ++ en Python. Tengo la siguiente clase de C ++.
El siguiente es un fragmento del código que estoy tratando de convertir:
/*packet_buffer.h*/ class CPacketBuffer { public: // construct based on given buffer, data is not copied CPacketBuffer(uint8_t* data, uint32_t length) { mpBuffer = data; mLength = length; mHead = 0; mTail = length; } uint8_t* GetBuffer() { return (mpBuffer + mHead); } void Add(const uint8_t* data, uint32_t length) { if ((mTail + length) > mLength) { length = (mLength - mTail); } //.... }
He estado tratando de escribir un archivo example.i que acepte punteros a typedefs (uint8_t *) todo el día de hoy usando la ayuda de la documentación de swig, pero no he tenido éxito.
El siguiente es un archivo packet_buffer.i que he intentado que no funciona.
%module packet_buffer %include typemaps.i %apply unsigned char* {uint8_t*}; %apply unit8_t *INPUT {uint8_t *data}; %{ #define SWIG_FILE_WITH_INIT #include "../include/packet_buffer.h" %} %include "../include/packet_buffer.h"
Si he entendido esto correctamente, el problema al que te enfrentas no es que sean indicadores, sino que son arreglos potencialmente ilimitados.
Puede deformar una matriz C sin límites utilizando carrays.i y la macro “% array_class”, por ejemplo:
%module packet %include "stdint.i" %{ #include "packet.h" %} %include "carrays.i" %array_class(uint8_t, buffer); %include "packet.h"
Entonces te permitiría escribir en Python algo como:
a = packet.buffer(10000000) p = packet.CPacketBuffer(a.cast(), 10000000)
Tenga en cuenta que deberá asegurarse de que la vida útil del búfer sea suficiente: si el objeto de Python se libera sin que el código de C ++ sea consciente, terminará con un comportamiento indefinido.
Puede convertir los punteros uint8_t*
(arreglos ilimitados) en instancias de búfer en Python usando los métodos de frompointer
que también crea la macro %array_class
, por ejemplo:
r = packet.GetBuffer() buf = packet.buffer_frompointer(r)
Puede agregar código Python adicional para automatizar / ocultar la mayor parte de la conversión entre buffers, si lo desea, o usar MemoryViews para integrarse más estrechamente con Python en el lado C API.
En general, aunque esto es C ++, sugeriría usar std::vector
para esto. Es mucho más agradable de usar en el lado de Python que los arreglos ilimitados y el costo es mínimo para la seguridad y simplicidad que le ofrece.