J'ai un petit projet qui fonctionne à merveille avec SWIG. En particulier, certains de mes fonctions renvoient std::vector
s, qui se traduit pour les tuples en Python. Maintenant, je fais beaucoup de nombres, je viens donc de SWIG convertir ces tableaux numpy une fois qu'ils sont retournés à partir du code c++. Pour ce faire, j'utilise quelque chose comme ce qui suit dans GORGÉE.
%feature("pythonappend") My::Cool::Namespace::Data() const %{ if isinstance(val, tuple) : val = numpy.array(val) %}
(En fait, il existe plusieurs fonctions de Données nommée, certaines de retour de flotte, c'est pourquoi j'ai vérifier qu' val
est en fait un n-uplet.) Cela fonctionne à merveille.
Mais, j'aimerais aussi utiliser l' -builtin
drapeau qui est maintenant disponible. Les appels à ces fonctions de Données sont rares et la plupart du temps interactive, de sorte que leur lenteur n'est pas un problème, mais il y a d'autres lente boucles d'accélérer de façon significative avec le groupe builtin option.
Le problème est que lorsque j'utilise le drapeau, la pythonappend fonction est ignorée en mode silencieux. Maintenant, les Données retourne un tuple de nouveau. Est-il possible que je pourrais toujours retourner les tableaux numpy? J'ai essayé d'utiliser typemaps, mais elle s'est transformée en un gigantesque gâchis.
Edit:
Borealid a répondu à la question très bien. Juste pour être complet, j'ai inclus un couple connexes, mais subtilement différentes typemaps que j'ai besoin parce que j'retour par référence const et j'utilise des vecteurs de vecteurs (ne commencez pas!). Ces sont suffisamment différentes pour que je ne veux pas que quelqu'un d'autre titubant à essayer de comprendre les différences mineures.
%typemap(out) std::vector<int>& {
npy_intp result_size = $1->size();
npy_intp dims[1] = { result_size };
PyArrayObject* npy_arr = (PyArrayObject*)PyArray_SimpleNew(1, dims, NPY_INT);
int* dat = (int*) PyArray_DATA(npy_arr);
for (size_t i = 0; i < result_size; ++i) { dat[i] = (*$1)[i]; }
$result = PyArray_Return(npy_arr);
}
%typemap(out) std::vector<std::vector<int> >& {
npy_intp result_size = $1->size();
npy_intp result_size2 = (result_size>0 ? (*$1)[0].size() : 0);
npy_intp dims[2] = { result_size, result_size2 };
PyArrayObject* npy_arr = (PyArrayObject*)PyArray_SimpleNew(2, dims, NPY_INT);
int* dat = (int*) PyArray_DATA(npy_arr);
for (size_t i = 0; i < result_size; ++i) { for (size_t j = 0; j < result_size2; ++j) { dat[i*result_size2+j] = (*$1)[i][j]; } }
$result = PyArray_Return(npy_arr);
}
Edit 2:
Bien que pas tout à fait ce que je cherchais, des problèmes similaires peuvent également être résolus à l'aide de @MOINE de l'approche (expliqué ici).