어떻게 Boost.Python 을 이용 하여 Python C/C++혼합 프로 그래 밍 을 실현 합 니까?
18361 단어 boost.pythonpython혼합 프로 그래 밍
학습 중 문제 가 발생 하면 홈 페이지 의 예 를 참고 하 세 요.
D:\boost_1_61_0\libs\python\test
참고:Boost.Python 의 영문 문서 입 니 다.
Boost.Python 을 이용 하여 Python C/C++혼합 프로 그래 밍 을 실현 합 니 다.
python 과 C++혼합 프로 그래 밍 에 대해 서 는 사실상 두 부분 이 있 습 니 다.
1.extending 에 있어 서 자주 사용 하 는 방안 은 boost.python 과 swig 입 니 다.
swig 는 접착 C++,PYTHON 입 니 다.제 앞 에 있 는 도형 에 이 진 트 리 를 표시 하 는 글 에서 언급 한 것 은 pyqt 를 인터페이스 로 하고 c+코드 를 사용 하여 swig 로 생 성 된.so 동적 라 이브 러 리 입 니 다.
boost.python 은 직접 전환 하여 py++를 이용 하여 필요 한 wrapper 를 자동 으로 생 성 할 수 있 습 니 다.이 방면 의 내용 에 대한 입문 은 boost.python 홈 페이지 를 제외 하고 중국어 입문 자 료 를 추천 합 니 다.
다음은 더 이상 할 말 이 없 으 니 상세 한 소 개 를 살 펴 봅 시다.
내 보 내기 함수
#include<string>
#include<boost/python.hpp>
using namespace std;
using namespace boost::python;
char const * greet()
{
return "hello,world";
}
BOOST_PYTHON_MODULE(hello_ext)
{
def("greet", greet);
}
python:
import hello_ext
print hello_ext.greet()
내 보 내기 클래스:기본 구조의 함수 클래스 내 보 내기
c++
#include<string>
#include<boost/python.hpp>
using namespace std;
using namespace boost::python;
struct World
{
void set(string msg) { this->msg = msg; }
string greet() { return msg; }
string msg;
};
BOOST_PYTHON_MODULE(hello) // module
{
class_<World>("World")
.def("greet", &World::greet)
.def("set", &World::set);
}
python:
import hello
planet = hello.World() # ,
planet.set("howdy") #
print planet.greet() #
구조 함수 내 보 내기:
#include<string>
#include<boost/python.hpp>
using namespace std;
using namespace boost::python;
struct World
{
World(string msg):msg(msg){} //
World(double a, double b):a(a),b(b) {} //
void set(string msg) { this->msg = msg; }
string greet() { return msg; }
double sum_s() { return a + b; }
string msg;
double a;
double b;
};
BOOST_PYTHON_MODULE(hello) // module
{
class_<World>("World",init<string>())
.def(init<double,double>()) // expose another construct
.def("greet", &World::greet)
.def("set", &World::set)
.def("sum_s", &World::sum_s);
}
python 테스트 호출:
import hello
planet = hello.World(5,6)
planet2 = hello.World("hollo world")
print planet.sum_s()
print planet2.greet()
구조 함 수 를 내 보 내지 않 으 려 면 no 를 사용 하 십시오.init:
class_<Abstract>("Abstract",no_init)
클래스 데이터 멤버
#include<string>
#include<boost/python.hpp>
using namespace std;
using namespace boost::python;
struct Var
{
Var(string name):name(name),value(){}
string const name;
float value;
};
BOOST_PYTHON_MODULE(hello_var)
{
class_<Var>("Var", init<string>())
.def_readonly("name", &Var::name) //
.def_readwrite("value", &Var::value); //
}
python 호출:
import hello_var
var = hello_var.Var("hello_var")
var.value = 3.14
# var.name = 'hello' # error
print var.name
C++클래스 대상 을 Python 의 클래스 대상 으로 내 보 냅 니 다.var.name 에서 값 을 부여 할 수 없 음 을 주의 하 십시오.클래스 속성
//
#include<string>
#include<boost/python.hpp>
using namespace std;
using namespace boost::python;
struct Num
{
Num(){}
float get() const { return val; }
void set(float val) { this->val = val; }
float val;
};
BOOST_PYTHON_MODULE(hello_num)
{
class_<Num>("Num")
.add_property("rovalue", &Num::get) // :
.add_property("value", &Num::get, &Num::set);// .value .rovalue , 。
}
python:
import hello_num
num = hello_num.Num()
num.value = 10
print num.rovalue # result: 10
이어받다
//
#include<string>
#include<iostream>
#include<boost/python.hpp>
using namespace std;
using namespace boost::python;
struct Base {
virtual ~Base() {};
virtual string getName() { return "Base"; }
string str;
};
struct Derived : Base {
string getName() { return "Derived"; }
};
void b(Base *base) { cout << base->getName() << endl; };
void d(Derived *derived) { cout << derived->getName() << endl; };
Base * factory() { return new Derived; }
/*
。
:http://stackoverflow.com/questions/38261530/unresolved-external-symbols-since-visual-studio-2015-update-3-boost-python-link/38291152#38291152
*/
namespace boost
{
template <>
Base const volatile * get_pointer<class Base const volatile >(
class Base const volatile *c)
{
return c;
}
}
BOOST_PYTHON_MODULE(hello_derived)
{
class_<Base>("Base")
.def("getName", &Base::getName)
.def_readwrite("str", &Base::str);
class_<Derived, bases<Base> >("Derived")
.def("getName", &Derived::getName)
.def_readwrite("str", &Derived::str);
def("b", b);
def("d", d);
def("factory", factory,
return_value_policy<manage_new_object>());//
}
python:
import hello_derived
derive = hello_derived.factory()
hello_derived.d(derive)
클래스 의 가상 함수:
/*
, : Python , C++
*/
#include<boost/python.hpp>
#include<boost/python/wrapper.hpp>
#include<string>
#include<iostream>
using namespace boost::python;
using namespace std;
struct Base
{
virtual ~Base() {}
virtual int f() { return 0; };
};
struct BaseWrap : Base, wrapper<Base>
{
int f()
{
if (override f = this->get_override("f"))
return f(); // ,
return Base::f(); //
}
int default_f() { return this->Base::f(); }
};
BOOST_PYTHON_MODULE(hello_virtual)
{
class_<BaseWrap, boost::noncopyable>("Base")
.def("f", &Base::f, &BaseWrap::default_f);
}
python:
import hello_virtual
base = hello_virtual.Base()
# , C++
class Derived(hello_virtual.Base):
def f(self):
return 42
derived = Derived()
print base.f()
print derived.f()
클래스 연산 자/특수 함수
// /
#include<string>
#include<iostream>
// #include<boost/python.hpp> ,
#include <boost/python/operators.hpp>
#include <boost/python/class.hpp>
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
#include <boost/operators.hpp>
using namespace std;
using namespace boost::python;
class FilePos
{
public:
FilePos() :len(0) {}
operator double()const { return len; };//
int len;
};
// operator
FilePos operator+(FilePos pos, int a)
{
pos.len = pos.len + a;
return pos; //
}
FilePos operator+(int a, FilePos pos)
{
pos.len = pos.len + a;
return pos; //
}
int operator-(FilePos pos1, FilePos pos2)
{
return (pos1.len - pos2.len);
}
FilePos operator-(FilePos pos, int a)
{
pos.len = pos.len - a;
return pos;
}
FilePos &operator+=(FilePos & pos, int a)
{
pos.len = pos.len + a;
return pos;
}
FilePos &operator-=(FilePos & pos, int a)
{
pos.len = pos.len - a;
return pos;
}
bool operator<(FilePos pos1, FilePos pos2)
{
if (pos1.len < pos2.len)
return true;
return false;
}
//
FilePos pow(FilePos pos1, FilePos pos2)
{
FilePos res;
res.len = std::pow(pos1.len, pos2.len);
return res;
}
FilePos abs(FilePos pos)
{
FilePos res;
res.len = std::abs(pos.len);
return res;
}
ostream& operator<<(ostream& out, FilePos pos)
{
out << pos.len;
return out;
}
BOOST_PYTHON_MODULE(hello_operator)
{
class_<FilePos>("FilePos")
.def_readwrite("len",&FilePos::len)
.def(self + int())
.def(int() + self)
.def(self - self)
.def(self - int())
.def(self += int())
.def(self -= other<int>())
.def(self < self)
.def(float_(self))// , __float__
.def(pow(self, other<FilePos>())) // __pow__
.def(abs(self)) // __abs__
.def(str(self)); // __str__ for ostream
}
위의:def(pow(self,otherpython:
import hello_operator
filepos1 = hello_operator.FilePos()
filepos1.len = 10
filepos2 = hello_operator.FilePos()
filepos2.len = 20;
print filepos1 - filepos2
함수.함수 호출 정책.
//
#include<string>
#include<iostream>
#include<boost/python.hpp>
using namespace std;
using namespace boost::python;
struct X
{
string str;
};
struct Z
{
int value;
};
struct Y
{
X x;
Z *z;
int z_value() { return z->value; }
};
X & f(Y &y, Z*z)
{
y.z = z;
return y.x; // x y ,x y 。 :Python C++
}
BOOST_PYTHON_MODULE(hello_call_policy)
{
class_<Y>("Y")
.def_readwrite("x", &Y::x)
.def_readwrite("z", &Y::z)
.def("z_value", &Y::z_value);
class_<X>("X")
.def_readwrite("str", &X::str);
class_<Z>("Z")
.def_readwrite("value", &Z::value);
// return_internal_reference<1 : (y x )。
// with_custodian_and_ward<1, 2> 。
def("f", f, return_internal_reference<1, with_custodian_and_ward<1, 2> >());
}
함수 과부하
// overloading
#include<string>
#include<iostream>
#include<boost/python.hpp>
using namespace std;
using namespace boost::python;
struct X
{
bool f(int a)
{
return true;
}
bool f(int a, double b)
{
return true;
}
bool f(int a, double b, char c)
{
return true;
}
int f(int a, int b, int c)
{
return a + b + c;
}
};
bool (X::*fx1)(int) = &X::f;
bool(X::*fx2)(int, double) = &X::f;
bool(X::*fx3)(int, double,char) = &X::f;
int(X::*fx4)(int, int,int) = &X::f;
BOOST_PYTHON_MODULE(hello_overloaded)
{
class_<X>("X")
.def("f", fx1)
.def("f", fx2)
.def("f", fx3)
.def("f", fx4);
}
python:
import hello_overloaded
x = hello_overloaded.X() # create a new object
print x.f(1) # default int type
print x.f(2,double(3))
print x.f(4,double(5),chr(6)) # chr(6) convert * to char
print x.f(7,8,9)
기본 매개 변수일반 함수 의 기본 매개 변수:
그러나 위 에서 재 부팅 함 수 를 봉인 할 때 기본 매개 변수 에 대한 정 보 를 잃 어 버 렸 습 니 다.물론 우 리 는 일반적인 형식의 포장 을 통 해 다음 과 같다.
int f(int,double = 3.14,char const * = "hello");
int f1(int x){ return f(x);}
int f2(int x,double y){return f(x,y)}
//int module init
def("f",f); //
def("f",f2); //
def("f",f1); //
하지만 위의 형식 으로 포장 하 는 것 은 번거롭다.우 리 는 매크로 형식 을 통 해 위의 기능 을 대량으로 완성 할 수 있다.C++:
// BOOST_PYTHON_FUNCTION_OVERLOADS
#include<string>
#include<iostream>
#include<boost/python.hpp>
using namespace std;
using namespace boost::python;
void foo(int a, char b = 1, unsigned c = 2, double d = 3)
{
return;
}
BOOST_PYTHON_FUNCTION_OVERLOADS(foo_overloads, foo, 1, 4); // 1, 4
BOOST_PYTHON_MODULE(hello_overloaded)
{
def("foo", foo, foo_overloads()); //
}
python:
import hello_overloaded
hello_overloaded.foo(1)
hello_overloaded.foo(1,chr(2))
hello_overloaded.foo(1,chr(2),3) # 3 C++ unsigned int
hello_overloaded.foo(1,chr(2),3,double(4))
구성원 함수 의 기본 매개 변수:
// BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS ,
#include<string>
#include<iostream>
#include<boost/python.hpp>
using namespace std;
using namespace boost::python;
struct george
{
void wack_em(int a, int b = 0, char c = 'x')
{
return;
}
};
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(george_overloads, wack_em, 1, 3); // 1, 3
BOOST_PYTHON_MODULE(hello_member_overloaded)
{
class_<george>("george")
.def("wack_em", &george::wack_em, george_overloads());
}
python:
import hello_member_overloaded
c = hello_member_overloaded.george()
c.wack_em(1)
c.wack_em(1,2)
c.wack_em(1,2,chr(3))
init 와 optional 을 이용 하여 구조 함수 의 재 부팅 을 실현 합 니 다.사용 방법 은 다음 과 같다.
// init optional
#include<string>
#include<iostream>
#include<boost/python.hpp>
using namespace std;
using namespace boost::python;
struct X
{
X(int a, char b = 'D', string c = "constructor", double b = 0.0) {}
};
BOOST_PYTHON_MODULE(hello_construct_overloaded)
{
class_<X>("X")
.def(init<int, optional<char, string, double> >()); // init optional
}
대상 인터페이스Python 은 동적 형식의 언어 이 고 C++는 정적 형식 입 니 다.Python 변 수 는 integer,float,list,dict,tuple,str,long 등 이 고 다른 유형 이 있 을 수 있 습 니 다.Boost.Python 과 C++의 관점 에서 볼 때 Python 의 변 수 는 클래스 object 의 인 스 턴 스 입 니 다.이 절 에서 Python 대상 을 어떻게 처리 하 는 지 보 겠 습 니 다.
기본 인터페이스
// init optional
#include<string>
#include<iostream>
#include<boost/python.hpp>
#include <numpy/arrayobject.h>
using namespace std;
using namespace boost::python;
namespace bp = boost::python;
void f(object x)
{
int y = extract<int>(x); // retrieve an int from x
}
int g(object x)
{
extract<int> get_int(x);
if (get_int.check())
return get_int();
else
return 0;
}
int test(object &x)
{
dict d = extract<dict>(x.attr("__dict__"));
d["whatever"] = 4;
return 0;
}
int test2(dict & d)
{
d["helloworld"] = 3;
return 0;
}
class A {
public:
list lst;
void listOperation(list &lst) {};
};
// np.array , C++
int add_arr_1(object & data_obj, object rows_obj, object cols_obj)
{
PyArrayObject* data_arr = reinterpret_cast<PyArrayObject*>(data_obj.ptr());
float * data = static_cast<float *>(PyArray_DATA(data_arr));
// using data
int rows = extract<int>(rows_obj);
int cols = extract<int>(cols_obj);
for (int i = 0; i < rows*cols; i++)
{
data[i] += 1;
}
return 0;
}
BOOST_PYTHON_MODULE(hello_object)
{
def("test", test);
def("test2", test2);
def("add_arr_1", add_arr_1);
}
python 호출:
import hello_object
dic1 = {"whatever":1}
hello_object.test2(dic1)
arr = np.array([1,2,3],dtype = float32)
print arr.dtype
print arr
hello_object.add_arr_1(arr,1,3)
print arr
요약:이상 은 이 글 의 전체 내용 입 니 다.본 논문 의 내용 이 여러분 의 학습 이나 업무 에 어느 정도 참고 학습 가치 가 있 기 를 바 랍 니 다.궁금 한 점 이 있 으 시 면 댓 글 을 남 겨 주 셔 서 저희 에 대한 지지 에 감 사 드 립 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
어떻게 Boost.Python 을 이용 하여 Python C/C++혼합 프로 그래 밍 을 실현 합 니까?extending 이른바 python 프로그램 에서 c/c+코드 를 호출 합 니 다.사실은 c+코드 를 먼저 처리 하고 미리 생 성 된 동적 링크 라 이브 러 리 입 니 다.예 를 들 어 example.so,pyth...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.