Embeding Python & Extending Python with FFPython

简介: Introduction 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.

Introduction

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.

  • When exception happens while invoking python function by boost.python, boost.python doesn't provide interface to fetch traceback information.
  • Boost python is a big lib to some extent. Someone will find it much difficult who just wants to try to experience how embedding Python works.
  • Boost.pyhon supports badly to extend python by using C++ static function and class in runtime. Boost.python recommends to use dynamic library to extending python.
  • Someone who wants to learn example code using Python API will find it difficult to understand well boost.python codes, in my opinion.
  • If you have the need to convert data between C++ STL container and python object builtin, you have to implement these codes yourself, while Python reference is so annoying.

FFPython

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.

Embedding Python

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.

  • Fetch global variable of python script(or module). This happens when you use Python script as config files.
  • Call python function in script. That is the most useful interface. Two parts of it are important.
    1. It should be supported to use C++ builtin type and C++ STL container as argument.
    2. It should be supported to convert returned value of Python builtin types (like list, tuple, dict, string...) to C++ builtin types.
  • Fetch exception information when exception happens, especially traceback information. Because of feature of dynamic type, exception regularly happens even in online server, let alone debugging time. ffpython will throw std exception when Python exception happens. So it is much easier to print or log traceback info by outputexception.what() .
  • ffpython support nine arguments.
  • ffpython implemented by C++ template to wrap Python API. It is easy to understand how it works if you see the code.
 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");

 

Extending Python

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.

  • ffpython supports to register C++ static function. C++ builtin types and STL container can be as arguments.
  • C++ class can be registered to Python.

Register C++ static function, all base type supported. Arg num can be nine.

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.

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");
};   

 

Summary

  • ffpython only one implements head file, it is easy to integrate to project.
  • ffpython is simply wrap for Python API, so it is efficient.
  • github: https://github.com/fanchy/ffpython
  • python2.5 python2.6 python2.7, win / linux
  • python3.x is being developed, but unfortunately, Python3.x API is so different to python2.x, even different between python3.2 and python3.3, Headache!!
目录
相关文章
|
5天前
|
人工智能 JSON 供应链
畅用7个月无影 JVS Claw |手把手教你把JVS改造成「科研与产业地理情报可视化大师」
LucianaiB分享零成本畅用JVS Claw教程(学生认证享7个月使用权),并开源GeoMind项目——将JVS改造为科研与产业地理情报可视化AI助手,支持飞书文档解析、地理编码与腾讯地图可视化,助力产业关系图谱构建。
23328 5
畅用7个月无影 JVS Claw |手把手教你把JVS改造成「科研与产业地理情报可视化大师」
|
15天前
|
缓存 人工智能 自然语言处理
我对比了8个Claude API中转站,踩了不少坑,总结给你
本文是个人开发者耗时1周实测的8大Claude中转平台横向评测,聚焦Claude Code真实体验:以加权均价(¥/M token)、内部汇率、缓存支持、模型真实性及稳定性为核心指标。
5250 25
|
10天前
|
人工智能 JSON BI
DeepSeek V4 来了!超越 Claude Sonnet 4.5,赶紧对接 Claude Code 体验一把
JeecgBoot AI专题研究 把 Claude Code 接入 DeepSeek V4Pro 的真实体验与避坑记录 本文记录我将 Claude Code 对接 DeepSeek 最新模型(V4Pro)后的真实体验,测试了 Skills 自动化查询和积木报表 AI 建表两个场景——有惊喜,也踩
3764 12
|
9天前
|
人工智能 缓存 BI
Claude Code + DeepSeek V4-Pro 真实评测:除了贵,没别的毛病
JeecgBoot AI专题研究 把 Claude Code 接入 DeepSeek V4Pro,跑完 Skills —— OA 审批、大屏、报表、部署 5 大实战场景后的真实体验 ![](https://oscimg.oschina.net/oscnet/up608d34aeb6bafc47f
3088 10
Claude Code + DeepSeek V4-Pro 真实评测:除了贵,没别的毛病
|
27天前
|
人工智能 自然语言处理 安全
Claude Code 全攻略:命令大全 + 实战工作流(建议收藏)
本文介绍了Claude Code终端AI助手的使用指南,主要内容包括:1)常用命令如版本查看、项目启动和更新;2)三种工作模式切换及界面说明;3)核心功能指令速查表,包含初始化、压缩对话、清除历史等操作;4)详细解析了/init、/help、/clear、/compact、/memory等关键命令的使用场景和语法。文章通过丰富的界面截图和场景示例,帮助开发者快速掌握如何通过命令行和交互界面高效使用Claude Code进行项目开发,特别强调了CLAUDE.md文件作为项目知识库的核心作用。
21072 64
Claude Code 全攻略:命令大全 + 实战工作流(建议收藏)