为C ++(指针)创建swig包装器到python

时间:2012-05-08 06:45:41

标签: python pointers swig distutils

我是一个非常新的swig,我正在尝试创建一个swig包装器,以便在python中使用一些C ++文件。我有以下C ++类。

以下是我要转换的代码片段:

/*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);
        }
//....
}

我一直在尝试使用swig文档的帮助编写一个可以接受指向typedef(uint8_t *)指针的example.i文件,但是我没有成功。

以下是我尝试过的无法正常工作的packet_buffer.i文件。

%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"
  1. 如何为指向typedef的成员函数编写swig代码?
  2. 我可以编写可以在代码中使用的常用%apply,还是必须为每个INPUT,OUTPUT参数编写详细信息?

1 个答案:

答案 0 :(得分:3)

如果我已经正确地理解了这个问题,那么你所面临的问题不在于它们是指针,而是它们可能是无限制的数组。

您可以使用carrays.i和“%array_class”宏来warp an unbounded C array,例如:

%module packet
%include "stdint.i"

%{
    #include "packet.h"
%}

%include "carrays.i"
%array_class(uint8_t, buffer);

%include "packet.h"

然后允许你在Python中编写如下内容:

a = packet.buffer(10000000) 
p = packet.CPacketBuffer(a.cast(), 10000000)

请注意,您需要确保缓冲区的生命周期足够 - 如果在没有C ++代码的情况下释放Python对象,您将最终得到未定义的行为。

您可以使用uint8_t*宏也创建的frompointer方法将%array_class指针(无界数组)转换为Python中的缓冲区实例,例如:

r = packet.GetBuffer()
buf = packet.buffer_frompointer(r)

如果需要,您可以add additional Python code自动/隐藏缓冲区之间的大部分转换,或者使用MemoryViews在C API端集成更紧密的Python。

一般情况下,虽然这是C ++,但我建议使用std::vector - 在Python端使用它比使用无界数组更好,并且它为您提供的安全性和简单性成本最低。