/* testswig.i */
%module testswig
%include "exception.i"
%{
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "testswig.h"
static int teststructErr = 0; // flag to save test struct error state
%}
%include "testswig.h"
// set exception handling for __getitem__
%exception tagteststruct::__getitem__ {
assert(!teststructErr);
$action
if ( teststructErr ){
teststructErr = 0; // clear flag for next time
SWIG_exception(SWIG_IndexError, "Index out of bounds");
}
}
// set exception handling for __setitem__
%exception tagteststruct::__setitem__ {
assert(!teststructErr);
$action
if ( teststructErr ){
teststructErr = 0; // clear flag for next time
SWIG_exception(SWIG_IndexError, "Index out of bounds");
}
}
// set exception handling for insert()
%exception tagteststruct::insert {
assert(!teststructErr);
$action
if ( teststructErr ){
teststructErr = 0; // clear flag for next time
SWIG_exception(SWIG_IndexError, "Index out of bounds");
}
}
// "extend" the structure with various methods
%extend tagteststruct{
// add a __getitem__ method to the structure to get values from the data array
double __getitem__(size_t i) {
if (i >= $self->len) {
teststructErr = 1;
return 0;
}
return $self->data[i];
}
// add a __setitem__ method to the structure to set values in the data array
void __setitem__(size_t i, double value) {
if ( i >= $self->len ){
teststructErr = 1;
return;
}
$self->data[i] = value;
}
size_t __len__(){
return $self->len;
}
void insert(size_t i, double value) {
if ( i >= $self->len ){
teststructErr = 1;
return;
}
$self->data[i] = value;
}
%typemap(in, noblock=1) const void *memo "";
struct tagteststruct * __deepcopy__(const void *memo) {
// copy structure
struct tagteststruct * scopy = %new_copy(*$self, struct tagteststruct);
// copy array within the structure
scopy->data = %new_copy_array($self->data, $self->len, double);
return scopy;
}
%clear const void *memo;
}
>>> from testswig import CreateStruct
>>> # create an instance of the structure with 10 elements
>>> x = CreateStruct(10)
>>> # set the 5th element of the data array to 1.3
>>> x[4] = 1.3
>>> # output the 5th element of the array
>>> print(x[4])
1.3
>>> # output the length of the array
>>> print(len(x))
10
>>> # create a copy
>>> import copy
>>> y = copy.deepcopy(x)
>>> print(len(y))
10
>>> print(y[4])
1.3
>>> y[4] = 3.4
>>> print(y[4])
3.4
>>> print(x[4]) # check x hasn't been altered
1.3
从查看在LAL的Swig接口中实现的
__deepcopy__
,找到用于分配和释放内存的Swigmacros,以及我自己的(!)example关于将Swig接口扩展到C
结构,我已经找到了如何为Swig包装结构创建__deepcopy__
方法。在重复我的gist,并扩展它以添加
__deepcopy__
方法,如下所示:假设您有一些
C
代码包含这样的结构:其中结构将包含一个
^{pr2}$data
长度为len
的数组。函数CreateStruct()
分配 用于结构实例化的内存,定义为如果您用SWIG包装它以便在python中使用,那么有一些类似python列表的方法可以用于, e、 g.从
data
数组中添加或获取项。为此,可以创建以下SWIG接口文件:在上面的示例中,它将以下方法添加到结构中:
__getitem__
:这允许像python中的列表项一样访问结构的data
数组,例如,使用x[0]
返回teststruct->data[0]
中的值__setitem__
:这允许将结构的data
数组值设置为python中的列表项,例如,使用x[0] = 1.2
设置{__len__
:这将返回使用len(x)
时data
数组的长度insert()
:这将一个值插入数组中的特定索引中,就像__getitem__
__deepcopy__
:这允许使用^{这个例子还展示了如何对这些方法执行一些异常检查,特别是确保请求的索引不超过数组的大小。在
要编译和使用此示例,可以执行以下操作(参见SWIG的tutorial):
^{4}$其中,
-I/usr/include/python2.7
标志指向包含Python.h
文件的路径。这个testswig_wrap.c
文件由swig
命令生成。在然后可以在python中使用该结构,如下例所示:
Swig包装的结构本身可以在一个类中,例如:
我们可以测试:
相关问题 更多 >
编程相关推荐