Начнём с того, что такое SWIG. Итак, это мега-штука, которая предоставляет интерфейс скриптовым языкам (PHP, Python, Tcl, etc) к коду на C/C++. На официальном сайте есть несколько туториалов, которые вкратце показывают как можно применить SWIG для того или иного языка и python в их числе. Вроде при попытке повторить действия никаких ошибок не происходит, однако почему-то никак не получалось получить доступ к описанной в C++ структуре и объявленной там же переменной.
Итак, данный пост содержит немного подправленые инструкции из туториала с официального сайта SWIG для python.
Файл example.cxx:
1 2 3 4 5 6 7 | /* File : example.cxx */ int add(int a, int b) { return a + b; } |
Файл example.i (файл swig’а, по которому строится интерфейс):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | /* example.i */ %module example %{ /* Put header files here or function declarations like below */ #define SWIG_FILE_WITH_INIT int add(int a, int b); struct V { double x,y,z; }; int t = 5; %} int t = 5; struct V { double x,y,z; }; int add(int a, int b) { return a + b; } |
Корявенько, но тем не менее, почему то другие комбинации не работали. Теперь посмотрим как это всё прикрутить к самом python’у:
1 2 3 4 5 6 7 | swig -c++ -python example.i && \ g++ -fPIC -c example.cxx && \ g++ -fPIC -c example_wrap.cxx -I/usr/local/include/python2.5 && \ g++ -shared example.o example_wrap.o -o _example.so |
После выполнения всех действием проверяем что получили:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | >>> import example >>> dir(example) ['V', 'V_swigregister', '__builtins__', '__doc__', '__file__', '__name__', '_example', '_newclass', '_object', '_swig_getattr', '_swig_property', '_swig_repr', '_swig_setattr', '_swig_setattr_nondynamic', 'add', 'cvar'] >>> example.cvar.t 5 >>> a = example.V() >>> a.x = 10.123 >>> a.x 10.122999999999999 >>> a.x = 10.12 >>> a.x 10.119999999999999 >>> a.x = 10.1 >>> a.x 10.1 >>> a.y 0.0 >>> a > >>> example.add(1, 6) 7 >>> example.add(1, 6.5) Traceback (most recent call last): File "", line 1, in TypeError: in method 'add', argument 2 of type 'int' >>> |
Видно, что не всё гладко с типом double, но, тем не менее, оно работает и этого было достаточно для меня в своё время.