Python的点点滴滴(C extending)

来源:互联网 发布:js弹出模态框 编辑:程序博客网 时间:2024/04/30 02:43

与Python相识一周年,重拾Python。

之前的开发中,发现实现GObject的代码有许多重复的编码工作,于是借助Python,花了几天时间写了一份代码生成工具,最终生成的框架代码(含各种注释)将近7000行。最近需要对之前的工作实现一个自动化测试工具,如使用C,工作将极为繁琐;不如重用Python,希望在这个方向仍能大放异彩。

该中间件产品为C语言API,虽然内部以GObject为对象封装,但有部分API直接基于C语言实现,因此有必要对所有的C语言API再次封装,用于在Python中调用。

在Python中,使用C语言扩展的方法举例如下:

1. Python C语言扩展(hello.c):

#include <Python.h>

#include <string.h>

extern int print( char * s );

/*  module functions */

static PyObject * /*  returns object */

message(PyObject *self, PyObject *args) /*  self unused in modules */

{ /*  args from Python call */

    char *fromPython, result[1024];

    if (! PyArg_Parse(args, "(s)", &fromPython)) /*  convert Python -> C */

        return NULL; /*  null=raise exception */

    else {

        print( fromPython );

        strcpy(result, "Hello, "); /*  build up C string */

        strcat(result, fromPython); /*  add passed Python string */

        return Py_BuildValue("s", result); /*  convert C -> Python */

    }

}

/*  registration table */

static PyMethodDef libhello_methods[] = {

    {"message", message, METH_VARARGS, "func doc"}, /*  name, &func, fmt, doc */

    {NULL, NULL, 0, NULL} /*  end of table marker */

};

/*  module definition structure */

static struct PyModuleDef libhellomodule = {

    PyModuleDef_HEAD_INIT,

    "libhello", /*  name of module */

    "mod doc", /*  module documentation, may be NULL */

    -1, /*  size of per-interpreter module state, −1=in global vars */

    libhello_methods /*  link to methods table */

};

/*  module initializer */

PyMODINIT_FUNC

PyInit_libhello() /*  called on first import */

{ /*  name matters if loaded dynamically */

    return PyModule_Create(&libhellomodule);

}

2. hello模块中调用的外部C代码(print.c):

#include <stdio.h>

 

int print( char * s )

{

        printf( "[C] String [%s] from Python\n", s );

}

3. Python主程序(main.py):

#!/usr/bin/python

 

import libhello

 

libhello.message( 'world' )

libhello.message( 'extending' )

4. 编译运行:

$gcc print.c -shared -o libprint.so

$gcc hello.c -shared -o libhello.so `pkg-config python-3.4 --cflags --libs` -L. -lprint

$./main.py

5. 输出:

[C] String [world] from Python

[C] String [extending] from Python

接下来就是编写一系列的Python Glue Code,用于调用中间件的各个API进行测试了。

0 0
原创粉丝点击