SWIG如何将C中的缓冲区(字符数组)和指针包装到Python中?
Swig的手册对我来说有点难懂。我正在把我的C语言库封装成Python,这样我就可以在Python中测试我的C代码。现在我想知道如何在Python中访问C语言的指针地址,
typedef struct _buffer_t {
char buf[1024];
char *next_ptr;
} buffer_t;
void parse_buffer(buffer_t * buf_p) {
buf_p -> next_ptr ++;
}
我想在C代码中做的事情如下:
buffer_t my_buf;
my_buf.next_ptr = my_buf.buf;
parse_buffer(&my_buf);
expect_equal(&(my_buf.buf)+1, my_buf.next_ptr);
我在Python中怎么做同样的事情呢?导入了SWIG封装的模块后,我在Python中得到了一个buffer_t类。
1 个回答
1
问题在于,SWIG 正在尝试将缓冲区当作字符串来处理,而字符串不仅仅是一个指针。对于 next_ptr
的赋值操作会分配内存并复制字符串,而不仅仅是指针的赋值。你可以通过几种方法来解决这个问题。
最简单的方法是使用 %extend
在 Python 中添加一个“重置缓冲区”的方法:
%extend {
void resetPtr() {
$self->next_ptr=$self->buf;
}
}
然后你可以在 Python 中调用这个方法来完成你想要的赋值操作。
另外,如果你想强制将缓冲区当作普通指针来处理,你可以让 SWIG 将这两个成员都当作 void*
来处理,而不是 char*
和 char[]
。我原本希望这能像对每种类型使用 %apply
那样简单,但在我的测试中,这似乎对 memberin 和 memberout 并不奏效:
%apply void * { char *next };
%apply void * { char buf[ANY] };
鉴于 memberin/memberout 的类型映射对于让这个工作至关重要,我认为 %extend
是最干净的解决方案。