Skip to content

Commit bfe7f4e

Browse files
committed
[INIT]
1 parent 29baa9d commit bfe7f4e

12 files changed

Lines changed: 8619 additions & 1 deletion

File tree

Makefile

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
2+
3+
.PHONY:all
4+
5+
all:
6+
g++ -o app_test example.cpp -I /usr/include/python2.6/ -L /usr/lib64/ -lpython2.6

README.md

Lines changed: 218 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,218 @@
1-
# PythonCpp
1+
# pythoncpp
2+
3+
pythoncpp is a c++ lib,which is to simplify task that embed python and extend python.
4+
For example, call python function, register c++ function to python, register c++ class to python.
5+
Only one implement c++ header file.
6+
7+
## Project Goals
8+
* easier to embed python script
9+
* easier to call python function
10+
* easier to set or get var in python script
11+
* easier to extend python with c++ static function
12+
* easier to extend python with c++ class. C++ class Once registed, python can use it like builtin type.
13+
* when python exception throw, pythoncpp will wrap it as a std exception which includes python traceback info.
14+
15+
## Supported Python versions
16+
* python2.5 python2.6 python2.7, win / linux
17+
* python3.x is being developed, but unfortunately, python3.x api is so different to python2.x, even diffent between python3.2
18+
and python3.3, Headache!!
19+
20+
## Embed Python script in C++
21+
### Get / Set varialbe in python script/module
22+
``` c++
23+
printf("sys.version=%s\n", pythoncpp.get_global_var<string>("sys", "version").c_str());
24+
pythoncpp.set_global_var("fftest", "global_var", "OhNice");
25+
printf("fftest.global_var=%s\n", pythoncpp.get_global_var<string>("fftest", "global_var").c_str());
26+
```
27+
### call python function, Support all base type as arg or return value. Nine args can be supported.
28+
``` c++
29+
int a1 = 100; float a2 = 3.14f; string a3 = "OhWell";
30+
pythoncpp.call<void>("fftest", "test_base", a1, a2, a3);
31+
```
32+
### call python function, Support all STL type as arg or return value. Nine args can be supported. Vector and List for tuple and list in python,map for dict in python.
33+
``` c++
34+
vector<int> a1;a1.push_back(100);a1.push_back(200);
35+
list<string> a2; a2.push_back("Oh");a2.push_back("Nice");
36+
vector<list<string> > a3;a3.push_back(a2);
37+
38+
pythoncpp.call<bool>("fftest", "test_stl", a1, a2, a3);
39+
typedef map<string, list<vector<int> > > ret_t;
40+
ret_t val = pythoncpp.call<ret_t>("fftest", "test_return_stl");
41+
```
42+
## Extend Python
43+
### register c++ static function, all base type supported. Arg num can be nine.
44+
``` c++
45+
static int print_val(int a1, float a2, const string& a3, const vector<double>& a4)
46+
{
47+
printf("%s[%d,%f,%s,%d]\n", __FUNCTION__, a1, a2, a3.c_str(), a4.size());
48+
return 0;
49+
}
50+
struct ops_t
51+
{
52+
static list<int> return_stl()
53+
{
54+
list<int> ret;ret.push_back(1024);
55+
printf("%s\n", __FUNCTION__);
56+
return ret;
57+
}
58+
};
59+
60+
void test_reg_function()
61+
{
62+
pythoncpp_t pythoncpp;//("ext1");
63+
pythoncpp.reg(&print_val, "print_val")
64+
.reg(&ops_t::return_stl, "return_stl");
65+
pythoncpp.init("ext1");
66+
pythoncpp.call<void>("fftest", "test_reg_function");
67+
}
68+
```
69+
### register c++ class, python can use it just like builtin types.
70+
``` c++
71+
72+
class foo_t
73+
{
74+
public:
75+
foo_t(int v_):m_value(v_)
76+
{
77+
printf("%s\n", __FUNCTION__);
78+
}
79+
virtual ~foo_t()
80+
{
81+
printf("%s\n", __FUNCTION__);
82+
}
83+
int get_value() const { return m_value; }
84+
void set_value(int v_) { m_value = v_; }
85+
void test_stl(map<string, list<int> >& v_)
86+
{
87+
printf("%s\n", __FUNCTION__);
88+
}
89+
int m_value;
90+
};
91+
92+
class dumy_t: public foo_t
93+
{
94+
public:
95+
dumy_t(int v_):foo_t(v_)
96+
{
97+
printf("%s\n", __FUNCTION__);
98+
}
99+
~dumy_t()
100+
{
101+
printf("%s\n", __FUNCTION__);
102+
}
103+
void dump()
104+
{
105+
printf("%s\n", __FUNCTION__);
106+
}
107+
};
108+
109+
110+
static foo_t* obj_test(dumy_t* p)
111+
{
112+
printf("%s\n", __FUNCTION__);
113+
return p;
114+
}
115+
116+
void test_register_base_class(pythoncpp_t& pythoncpp)
117+
{
118+
pythoncpp.reg_class<foo_t, PYCTOR(int)>("foo_t")
119+
.reg(&foo_t::get_value, "get_value")
120+
.reg(&foo_t::set_value, "set_value")
121+
.reg(&foo_t::test_stl, "test_stl")
122+
.reg_property(&foo_t::m_value, "m_value");
123+
124+
pythoncpp.reg_class<dumy_t, PYCTOR(int)>("dumy_t", "dumy_t class inherit foo_t ctor <int>", "foo_t")
125+
.reg(&dumy_t::dump, "dump");
126+
127+
pythoncpp.reg(obj_test, "obj_test");
128+
129+
pythoncpp.init("ext2");
130+
pythoncpp.call<void>("fftest", "test_register_base_class");
131+
};
132+
```
133+
### Register c++ class which inherit a class having been registered.
134+
``` c++
135+
pythoncpp.call<void>("fftest", "test_register_inherit_class");
136+
```
137+
### C++ object pointer can be as a arg to python, and object can be access as a instance of builtin type in python.
138+
``` c++
139+
void test_cpp_obj_to_py(pythoncpp_t& pythoncpp)
140+
{
141+
foo_t tmp_foo(2013);
142+
pythoncpp.call<void>("fftest", "test_cpp_obj_to_py", &tmp_foo);
143+
}
144+
void test_cpp_obj_py_obj(pythoncpp_t& pythoncpp)
145+
{
146+
dumy_t tmp_foo(2013);
147+
148+
foo_t* p = pythoncpp.call<foo_t*>("fftest", "test_cpp_obj_py_obj", &tmp_foo);
149+
}
150+
```
151+
## Python test script
152+
``` python
153+
def test_base(a1, a2, a3):
154+
print('test_base', a1, a2, a3)
155+
return 0
156+
157+
def test_stl(a1, a2, a3):
158+
print('test_stl', a1, a2, a3)
159+
return True
160+
161+
def test_return_stl():
162+
print('test_return_stl')
163+
#map<string, list<vector<int> > >
164+
ret = {'Oh':[[111,222], [333, 444] ] }
165+
return ret
166+
167+
def test_reg_function():
168+
import ext1
169+
ext1.print_val(123, 45.6 , "----789---", [3.14])
170+
ret = ext1.return_stl()
171+
print('test_reg_function', ret)
172+
173+
def test_register_base_class():
174+
import ext2
175+
foo = ext2.foo_t(20130426)
176+
print("test_register_base_class get_val:", foo.get_value())
177+
foo.set_value(778899)
178+
print("test_register_base_class get_val:", foo.get_value(), foo.m_value)
179+
foo.test_stl({"key": [11,22,33] })
180+
print('test_register_base_class test_register_base_class', foo)
181+
182+
def test_register_inherit_class():
183+
import ext2
184+
dumy = ext2.dumy_t(20130426)
185+
print("test_register_inherit_class get_val:", dumy.get_value())
186+
dumy.set_value(778899)
187+
print("test_register_inherit_class get_val:", dumy.get_value(), dumy.m_value)
188+
dumy.test_stl({"key": [11,22,33] })
189+
dumy.dump()
190+
print('test_register_inherit_class', dumy)
191+
192+
def test_cpp_obj_to_py(foo):
193+
import ext2
194+
print("test_cpp_obj_to_py get_val:", foo.get_value())
195+
foo.set_value(778899)
196+
print("test_cpp_obj_to_py get_val:", foo.get_value(), foo.m_value)
197+
foo.test_stl({"key": [11,22,33] })
198+
print('test_cpp_obj_to_py test_register_base_class', foo)
199+
200+
def test_cpp_obj_py_obj(dumy):
201+
import ext2
202+
print("test_cpp_obj_py_obj get_val:", dumy.get_value())
203+
dumy.set_value(778899)
204+
print("test_cpp_obj_py_obj get_val:", dumy.get_value(), dumy.m_value)
205+
dumy.test_stl({"key": [11,22,33] })
206+
dumy.dump()
207+
ext2.obj_test(dumy)
208+
print('test_cpp_obj_py_obj', dumy)
209+
210+
return dumy
211+
212+
```
213+
214+
## Summary
215+
* pythoncpp Only One implement head file, it is easy to itegrate to project.
216+
* pythoncpp is simplely wrap for python api, so it is efficient.
217+
218+

0 commit comments

Comments
 (0)