From: William S F. <ws...@fu...> - 2009-03-20 09:05:53
|
Matteo wrote: > Re-posting in more simple and precise terms from a previous thread > http://groups.google.it/group/comp.lang.python/browse_thread/thread/6... > > Problem: > SWIG doesn't properly wrap c++ arrays of pointers, therefore when you > try to call a c++ function which requires them, a TypeError exception > is raised. > > Similar story here: > http://osdir.com/ml/programming.swig/2003-02/msg00064.html > > Already tried: > - some ctypes functions > - tuple or string instead of list > > Possibile solutions: > something like > http://embedded.eecs.berkeley.edu/Alumni/pinhong/scriptEDA/pyTypemapF... > that didn't work either, but I think I was not able to adapt the code > to my case, since the example is poorly explained. > > Code to reproduce error: > I made a dptest.cpp function that calculates the sum of an array of > pointers to ints. > > #include "dptest.h" > //the header file is just > //int sum(int**, int); > > int sum(int** dp, int len){ > int sum = 0; > for (int i = 0; i < len; i++){ > sum += *(dp[i]); > } > return sum; > > } > > swig -c++ -python, then setup.py build_ext --inplace gets it nicely > compiled and wrapped for python use. It also is imported without > problems, but then... > > matteo@matteo:~/lab/sandbox$ python > Python 2.5.2 (r252:60911, Oct 5 2008, 19:24:49) > [GCC 4.3.2] on linux2 > Type "help", "copyright", "credits" or "license" for more information. > >>> import dptest as dp > >>> l = [1, 2, 3, 4] > >>> size = len(l) > >>> dp.sum(l,size) > > Traceback (most recent call last): > File "<stdin>", line 1, in <module> > TypeError: in method 'sum', argument 1 of type 'int **' > > NOTE: A pure c++ program works as expected: > > #include <iostream> > > int sum(int**, int); > > int main(){ > int **array_of_ptr = new int*[4]; > for (int i = 0; i < 4; i++){ > array_of_ptr[i] = new int; > *array_of_ptr[i] = i+1; //fill it with 1,2,3,4: 1+2+3+4 = 10 > } > std::cout << sum(array_of_ptr, 4) << std::endl; > > } > > int sum(int** dp, int len){ > int sum = 0; > for (int i = 0; i < len; i++){ > sum += *(dp[i]); > } > return sum; > > } > > compiling and running prints the correct result: > matteo@matteo:~/lab/sandbox$ ./purecpp > 10 The default typemaps for pointer to pointers do not assume that it is an array of integer pointers. There is nothing in the type int ** that suggests that this is the only case -- there are other possibilities that int ** could be used for. As such the appropriate typemaps need writing. I can't think of any library typemaps you can use, but there must be some around somewhere if you search for them, otherwise write them yourself. William |