ffpython is a c++ lib,which is to simplify task that embed python and extend python. For example, call python function, register c++ function to python, register c++ class to python. Only one implement c++ header file.
- easier to embed python script
- easier to call python function
- easier to set or get var in python script
- easier to extend python with c++ static function
- easier to extend python with c++ class. C++ class Once registed, python can use it like builtin type.
- when python exception throw, ffpython will wrap it as a std exception which includes python traceback info.
- python2.5 python2.6 python2.7 python3, win / linux
printf("sys.version=%s\n", ffpython.get_global_var<string>("sys", "version").c_str());
ffpython.set_global_var("fftest", "global_var", "OhNice");
printf("fftest.global_var=%s\n", ffpython.get_global_var<string>("fftest", "global_var").c_str()); int a1 = 100; float a2 = 3.14f; string a3 = "OhWell";
ffpython.call<void>("fftest", "test_base", a1, a2, a3);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.
vector<int> a1;a1.push_back(100);a1.push_back(200);
list<string> a2; a2.push_back("Oh");a2.push_back("Nice");
vector<list<string> > a3;a3.push_back(a2);
ffpython.call<bool>("fftest", "test_stl", a1, a2, a3);
typedef map<string, list<vector<int> > > ret_t;
ret_t val = ffpython.call<ret_t>("fftest", "test_return_stl");class foo_t
{
public:
foo_t(int v_):m_value(v_)
{
printf("%s\n", __FUNCTION__);
}
virtual ~foo_t()
{
printf("%s\n", __FUNCTION__);
}
int get_value() const { return m_value; }
void set_value(int v_) { m_value = v_; }
void test_stl(map<string, list<int> >& v_)
{
printf("%s\n", __FUNCTION__);
}
int m_value;
};
class dumy_t: public foo_t
{
public:
dumy_t(int v_):foo_t(v_)
{
printf("%s\n", __FUNCTION__);
}
~dumy_t()
{
printf("%s\n", __FUNCTION__);
}
void dump()
{
printf("%s\n", __FUNCTION__);
}
};
static foo_t* obj_test(dumy_t* p)
{
printf("%s\n", __FUNCTION__);
return p;
}
ffpython.call<void>("fftest", "test_register_inherit_class");C++ object pointer can be as a arg to python, and object can be access as a instance of builtin type in python.
void test_cpp_obj_to_py(ffpython_t& ffpython)
{
foo_t tmp_foo(2013);
ffpython.call<void>("fftest", "test_cpp_obj_to_py", &tmp_foo);
}
void test_cpp_obj_py_obj(ffpython_t& ffpython)
{
dumy_t tmp_foo(2013);
foo_t* p = ffpython.call<foo_t*>("fftest", "test_cpp_obj_py_obj", &tmp_foo);
}static int print_val(int a1, float a2, const string& a3, const vector<double>& a4)
{
printf("%s[%d,%f,%s,%d]\n", __FUNCTION__, a1, a2, a3.c_str(), a4.size());
return 0;
}
struct ops_t
{
static list<int> return_stl()
{
list<int> ret;ret.push_back(1024);
printf("%s\n", __FUNCTION__);
return ret;
}
};
std::string test_reg_function(ffpython_t& ffpython)
{
ffpython.reg(&print_val, "print_val")
.reg(&ops_t::return_stl, "return_stl");
ffpython.reg_class<foo_t, PYCTOR(int)>("foo_t")
.reg(&foo_t::get_value, "get_value")
.reg(&foo_t::set_value, "set_value")
.reg(&foo_t::test_stl, "test_stl")
.reg_property(&foo_t::m_value, "m_value");
ffpython.reg_class<dumy_t, PYCTOR(int)>("dumy_t", "dumy_t class inherit foo_t ctor <int>", "foo_t")
.reg(&dumy_t::dump, "dump");
ffpython.reg(obj_test, "obj_test");
return "cppext";
}
def test_base(a1, a2, a3):
print('test_base', a1, a2, a3)
return 0
def test_stl(a1, a2, a3):
print('test_stl', a1, a2, a3)
return True
def test_return_stl():
print('test_return_stl')
#map<string, list<vector<int> > >
ret = {'Oh':[[111,222], [333, 444] ] }
return ret
def test_reg_function():
import cppext
cppext.print_val(123, 45.6 , "----789---", [3.14])
ret = cppext.return_stl()
print('test_reg_function', ret)
def test_register_base_class():
import cppext
foo = cppext.foo_t(20130426)
print("test_register_base_class get_val:", foo.get_value())
foo.set_value(778899)
print("test_register_base_class get_val:", foo.get_value(), foo.m_value)
foo.test_stl({"key": [11,22,33] })
print('test_register_base_class test_register_base_class', foo)
def test_register_inherit_class():
import cppext
dumy = cppext.dumy_t(20130426)
print("test_register_inherit_class get_val:", dumy.get_value())
dumy.set_value(778899)
print("test_register_inherit_class get_val:", dumy.get_value(), dumy.m_value)
dumy.test_stl({"key": [11,22,33] })
dumy.dump()
print('test_register_inherit_class', dumy)
def test_cpp_obj_to_py_ext(foo):
print('test_cpp_obj_to_py_ext', len(foo))
for k in range(0, len(foo)):
print('test_cpp_obj_to_py_ext', k, foo[k].m_value)
def test_cpp_obj_to_py(foo):
import cppext
print("test_cpp_obj_to_py get_val:", foo.get_value())
foo.set_value(778899)
print("test_cpp_obj_to_py get_val:", foo.get_value(), foo.m_value)
foo.test_stl({"key": [11,22,33] })
foo.m_value = 100
print('test_cpp_obj_to_py test_register_base_class', foo)
def test_cpp_obj_py_obj(dumy):
import cppext
print("test_cpp_obj_py_obj get_val:", dumy.get_value())
dumy.set_value(778899)
print("test_cpp_obj_py_obj get_val:", dumy.get_value(), dumy.m_value)
dumy.test_stl({"key": [11,22,33] })
dumy.dump()
cppext.obj_test(dumy)
print('test_cpp_obj_py_obj', dumy)
return dumy
class pyclass_t:
def __init__(self):
print('pyclass_t init....')
def sayHi(self, a1, a2):
print('sayHi..', a1, a2)
def test_cpp_obj_return_py_obj():
return pyclass_t()
def test_cpp_obj_return_py_lambda():
def test_lambda(a1):
print('test_lambda....', a1)
return test_lambda- ffpython Only One implement head file, it is easy to itegrate to project.
- ffpython is simplely wrap for python api, so it is efficient.