I a very new to swig and I am trying to create a swig wrapper in order to use a few C++ files in python. I have the following C++ class.
The following is a snippet of the code that I am trying to convert:
/*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);
}
//....
}
I have been trying to write a example.i file that would accept pointers to typedefs(uint8_t *) all day today using help from swig documentation, but I have been unsuccessful.
The following is a packet_buffer.i file that I have tried which doesn't work.
%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"
- How do I write a swig code for member functions that take pointers to typedefs?
- Can I write a common %apply that can be used across the code or will I have to write specifics for each INPUT, OUTPUT parameter?
If I've understood this correctly the problem you're facing isn't that they're pointers, it's that they're potentially unbounded arrays.
You can warp an unbounded C array using carrays.i and the "%array_class" macro, e.g.:
%module packet
%include "stdint.i"
%{
#include "packet.h"
%}
%include "carrays.i"
%array_class(uint8_t, buffer);
%include "packet.h"
Would then allow you to in Python write something like:
a = packet.buffer(10000000)
p = packet.CPacketBuffer(a.cast(), 10000000)
Note that you'll need to ensure the life of the buffer is sufficient - if the Python object gets released without the C++ code being aware you'll end up with undefined behaviour.
You can convert uint8_t*
pointers (unbounded arrays) to buffer instances in Python using the frompointer
methods that the %array_class
macro also creates, e.g.:
r = packet.GetBuffer()
buf = packet.buffer_frompointer(r)
You can add additional Python code to automate/hide most of the conversion between buffers if desired, or use MemoryViews to integrate tighter with Python on the C API side.
In general though since this is C++ I'd suggest using std::vector
for this - it's much nicer to use on the Python side than the unbounded arrays and the cost is minimal for the safety and simplicity it gives you.
来源:https://stackoverflow.com/questions/10493915/creating-swig-wrapper-for-c-pointers-to-python