精通
英语
和
开源
,
擅长
开发
与
培训
,
胸怀四海
第一信赖
锐英源精品开源,禁止转载和任何形式的非法内容使用,违者必究
ffpython is a C++ lib, which is to simplify tasks that embed Python and extend Python. As the author, I am a developer for MMO server. Mainly I use C++ to implement part that needs to response user's requests in realtime, while other logic part that needs to be modified frequently is implemented by Python. Python makes it possible to reload our part of the server when the server is running. Python is so easy that even my colleague with no programing skills can implement some npc script. When I was first in charge of integrating Python runtime interpreter to our C++ server, I used Boost.python. Somehow Boost.python helped me solve most problems about Python API especially parts of Python reference. But Boost.python is not perfect.ffpython是C ++库,用于简化嵌入Python和扩展Python的任务。作为作者,我是MMO服务器的开发人员。我主要使用C ++实现需要实时响应用户请求的部分,而其他需要经常修改的逻辑部分则由Python实现。使用Python,可以在服务器运行时重新加载服务器的一部分。Python非常简单,即使我没有编程技能的同事也可以实现一些npc脚本。当我第一次负责将Python运行时解释器集成到我们的C ++服务器时,我使用了Boost.python。Boost.python以某种方式帮助我解决了有关Python API的大多数问题,尤其是Python参考的某些部分。但是Boost.python并不完美。
Firstly, I implemented it just for converting data between C++ STL container and python object. Some of my colleagues have writes a lot of code using Python API directly. But there is some trap in some Python API even engineers who have a lot of experience using Python may have lost. PyDict_SetItem will auto increase reference key and value arguments, but other Python builtin structure API like PyTuple_SetItem will not increase reference the argument. It will cause memory leak. So I wanted to wrap operations about converting data between C++ STL container and Python builtin structure. Finally, I found some elegant ways to wrap embedding Python and extending Python by C++ template skills. So that is how FFPyhton was born.首先,我实现了它,仅用于在C ++ STL容器和python对象之间转换数据。我的一些同事直接使用Python API编写了很多代码。但是在某些Python API中仍然存在一些陷阱,即使具有丰富使用Python经验的工程师也可能会迷失方向。PyDict_SetItem将自动增加引用键和值参数,但其他Python内置结构API PyTuple_SetItem 不会增加引用参数。它将导致内存泄漏。所以我想包装有关在C ++ STL容器和Python内置结构之间转换数据的操作。最后,我找到了一些优雅的方法来包装嵌入的Python和通过C ++模板技能扩展Python。这就是FFPyhton的诞生方式。
Sometimes I think it's easier to show codes to readers here. ^_^. But it will be forbidden by administrator if I post lots of code. O(n_n)O~. So see code files or Github.
When Embedding Python, such functions are most needed.
有时我认为在这里向读者显示代码更容易。^ _ ^。但是如果我发布很多代码,它将被管理员禁止。O(N_N)O〜。因此,请参阅代码文件或Github。
嵌入Python时,最需要这些功能。
printf("sys.version=%s\n",
ffpython.get_global_var<string>("sys", "version").c_str());
int a1 = 100; float a2 = 3.14f; string a3 = "OhWell";
ffpython.call<void>("fftest", "test_base", a1, a2, a3);
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");
ffpython recommends to register C++ function/class in runtime. It works to design and develop MMO game server. So that is common use for me. There are some key points when embedding Python.
Register C++ static function, all base type supported. Arg num can be nine.ffpython建议在运行时注册C ++函数/类。它致力于设计和开发MMO游戏服务器。所以这对我来说很普遍。嵌入Python时有一些关键点。
注册C ++ static 函数,支持所有基本类型。Arg num可以是9。
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;
}
ffpython_t ffpython;//("ext1");
ffpython.reg(&print_val, "print_val");
ffpython.init("ext1");
Register C++ class, Python can use it just like builtin types.注册C ++类,Python可以像内置类型一样使用它。
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;
}
void test_register_base_class(ffpython_t& ffpython)
{
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");
};