在C程序中内嵌Python解释器 用脚本语言实现灵活的Plugin机制

在经历过的一些大型项目中,很难独立使用一种开发语言完成任务,由于我这边的业务项目通常以服务器方面居多,从项目周期和运营维护角度考虑,既要考虑到程序的性能,又要考虑到业务功能变更和维护的便利性。
很多时候,我们都会以Python进行框架开发,在一些涉及到性能要求的时候以内嵌C模块的形式进行扩展,以提高整个项目的执行效率。然而我们还有很多以C语言开发的服务器项目,通常使用Prefork、MPM等多进程或多线程的框架,那么怎么才能做到灵活的对这些服务器程序的业务扩展或是Plugin功能呢?
以前在纯C语言时,我们通常采用so lib或是dlopen的方法,这样每次增加或是调整业务模块都需要重新编译业务模块程序,使得联调和Debug相对比较复杂,现在我们可以采用另一种方式,在服务器端程序中嵌入Python解释器,在C程序中需要Kook的地方,以Python程序进行业务处理,灵活的实现Plugin机制,这样对于需要灵活业务调整、联调Debug时,带来了很大的便利性。

现在以一个小的示例程序,介绍在C程序中如何嵌入Python解释器,及如何载入Python脚本程序。

/**
 * @file test.c
 * gcc -Wall -O2 -o test test.c -I/usr/include/python2.7 -L/usr/lib -lpython2.7 -Wl,-R/usr/local/lib
 */
#include <stdio.h>
#include <string.h>
#include <Python.h>
 
int main(int argc, char *argv[])
{
    PyObject *pmod  = NULL;
    PyObject *pstr  = NULL;
    PyObject *pfunc = NULL;
    PyObject *pargs = NULL;
 
    char *cstr = NULL;
 
    /* 初始化解释器 */
    Py_Initialize();
 
    /* 构建一个元组保存参数, PyEval_CallObject的第二参数是一个元组 */
    pargs = Py_BuildValue("(s)", argv[1]);
 
    /* 添加Python路径, 包括当前路径, 否则不能导入当前路径下的模块 */
    PyRun_SimpleString("import sys;sys.path.append('.')");
 
    /* 导入模块名称, 通常为调用的Python脚本程序名 */
    pmod = PyImport_ImportModule("testpy");
    if (pmod == NULL) {
        printf("import module failed!\n");
        return -1;
    }
 
    /* 获得导入模块的函数属性 */
    pfunc = PyObject_GetAttrString(pmod, "testpy");
    if (pfunc == NULL) {
        printf("No such attribute!\n");
        return -1;
    }
 
    /* 调用导入模块的入口函数, 获取返回结果 */
    pstr = PyEval_CallObject(pfunc, pargs);
    if (pstr == NULL) {
        printf("callobject failed!\n");
        return -1;
    }
 
    /* 分析返回的结果 */
    PyArg_Parse(pstr, "s", &cstr);
 
    printf("%s\n", cstr);
 
    /* 关闭解释器 */
    Py_Finalize();
 
    return 0;
}

在C程序中嵌入的Python脚本程序示例,testpy.py:

#!/usr/bin/env python
 
import sys
 
def testpy(name):
 
    if not name:
        return 'Valid Arguments'
 
    str = "hello, " + name
 
    return str

程序运行结果:

~/prg/mypython$ ./test world!

hello, world!

一个更简单的例子:

/*
 * gcc -Wall -O2 -o test_python test_python.c -I/usr/include/python2.7 -L/usr/lib -lpython2.7
 */
#include <Python.h>
int main(int argc, char *argv[])
{
        Py_Initialize();
        PyRun_SimpleString("from time import time,ctime");
        PyRun_SimpleString("print 'Today is',ctime(time()) ");
        PyRun_SimpleString("print '^oo^'");
        Py_Finalize();
        return 0;
}

$ ./test_python 

Today is Mon Mar 14 00:08:41 2016

^oo^


转载于:https://my.oschina.net/u/2245781/blog/636112

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值