La manera más fácil de hacerlo es envolver sus matrices dentro de un struct
, que puede proporcionar extra methods to meet the "subscriptable" requirements.
He reunido un pequeño ejemplo. Supone que estás usando C++, pero la versión C equivalente es bastante trivial para construir a partir de esto, solo requiere un poco de repetición.
En primer lugar, la cabecera de C++ que tiene el struct
queremos envolver y una plantilla que usamos para envolver las matrices de tamaño fijo:
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;
Nuestra interfaz SWIG correspondiente a continuación, se ve algo como:
%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>;
El truco es que hemos utilizado %extend
para suministrar __getitem__
que es lo que Python usa para lecturas de subíndice y __setitem__
para las escrituras. (También podríamos haber suministrado un __iter__
para hacer que el tipo sea iterable). También le dimos a wraped_array
s específicos que deseamos utilizar nombres únicos para que SWIG los envuelva en la salida.
Con la interfaz suministrado ahora podemos hacer:
>>> 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
También puede encontrar this approach útil/interesante como alternativa.