最簡單的方法是將您的陣列包裝在struct
內,然後可以提供extra methods to meet the "subscriptable" requirements。
我已經放在一個小例子。它假定你使用的是C++,但是相應的C版本由此構建起來相當簡單,只需要一點點重複。
首先亮相,在C++頭有我們想要包裹struct
和我們用來包裹固定大小的數組模板:
template <typename Type, size_t N>
struct wrapped_array {
Type data[N];
};
typedef struct {
wrapped_array<int, 40> icntl;
wrapped_array<double, 15> cntl;
int *irn, *jcn;
} Test;
我們相應痛飲接口,則看起來像:
%module test
%{
#include "test.h"
#include <exception>
%}
%include "test.h"
%include "std_except.i"
%extend wrapped_array {
inline size_t __len__() const { return N; }
inline const Type& __getitem__(size_t i) const throw(std::out_of_range) {
if (i >= N || i < 0)
throw std::out_of_range("out of bounds access");
return self->data[i];
}
inline void __setitem__(size_t i, const Type& v) throw(std::out_of_range) {
if (i >= N || i < 0)
throw std::out_of_range("out of bounds access");
self->data[i] = v;
}
}
%template (intArray40) wrapped_array<int, 40>;
%template (doubleArray15) wrapped_array<double, 15>;
訣竅是我們用%extend
來提供__getitem__
這是Python用於下標讀取和__setitem__
寫入。 (我們也可以提供一個__iter__
來使類型可迭代)。我們還給出了具體的wraped_array
,我們希望使用唯一的名稱使SWIG將它們包裝在輸出中。
使用隨機提供的接口,我們現在可以做的:
>>> import test
>>> foo = test.Test()
>>> foo.icntl[30] = -654321
>>> print foo.icntl[30]
-654321
>>> print foo.icntl[40]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "test.py", line 108, in __getitem__
def __getitem__(self, *args): return _test.intArray40___getitem__(self, *args)
IndexError: out of bounds access
您也可能會發現this approach有用/有趣的選擇。