Я начал свое путешествие с привязки Python <-> C ++ с этой страницы с целью связать высокоуровневые типы данных (многомерные векторы STL со списками Python): -)
Испытав решения на основе ctypes и boost.python (и не будучи инженером-программистом), я нашел их сложными, когда требуется связывание типов данных высокого уровня, в то время как я нашли SWIG гораздо проще для таких случаев.
Таким образом, в этом примере используется SWIG, и он был протестирован в Linux (но SWIG доступен и также широко используется в Windows).
Цель состоит в том, чтобы сделать функцию C ++ доступной для Python, которая принимает матрицу в форме 2D-вектора STL и возвращает среднее значение каждой строки (как 1D-вектор STL).
Код на C ++ ("code.cpp") выглядит следующим образом:
#include <vector>
#include "code.h"
using namespace std;
vector<double> average (vector< vector<double> > i_matrix) {
// Compute average of each row..
vector <double> averages;
for (int r = 0; r < i_matrix.size(); r++){
double rsum = 0.0;
double ncols= i_matrix[r].size();
for (int c = 0; c< i_matrix[r].size(); c++){
rsum += i_matrix[r][c];
}
averages.push_back(rsum/ncols);
}
return averages;
}
Эквивалентный заголовок ("code.h"):
#ifndef _code
#define _code
#include <vector>
std::vector<double> average (std::vector< std::vector<double> > i_matrix);
#endif
Сначала мы скомпилируем код C ++ для создания объектного файла:
g++ -c -fPIC code.cpp
Затем мы определяем файл определения интерфейса SWIG ("code.i") для наших функций C ++.
%module code
%{
#include "code.h"
%}
%include "std_vector.i"
namespace std {
/* On a side note, the names VecDouble and VecVecdouble can be changed, but the order of first the inner vector matters! */
%template(VecDouble) vector<double>;
%template(VecVecdouble) vector< vector<double> >;
}
%include "code.h"
Используя SWIG, мы генерируем исходный код интерфейса C ++ из файла определения интерфейса SWIG.
swig -c++ -python code.i
Наконец, мы скомпилировали сгенерированный исходный файл интерфейса C ++ и соединили все вместе, чтобы сгенерировать разделяемую библиотеку, которая напрямую импортируется Python (значение «_»):
g++ -c -fPIC code_wrap.cxx -I/usr/include/python2.7 -I/usr/lib/python2.7
g++ -shared -Wl,-soname,_code.so -o _code.so code.o code_wrap.o
Теперь мы можем использовать функцию в скриптах Python:
#!/usr/bin/env python
import code
a= [[3,5,7],[8,10,12]]
print a
b = code.average(a)
print "Assignment done"
print a
print b