博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
巧用 python 脚本控制你的C程序(首发在我的博客园)
阅读量:7034 次
发布时间:2019-06-28

本文共 4054 字,大约阅读时间需要 13 分钟。

hot3.png

python是一门艺术语言,除了开发桌面程序,还能够开发网络应用,数据库应用,还可以代替shell编写一些的实用脚本,本文主要讲述了如何利用 python 程序控制你的 C 程序的行为。

作为例子,本文将用 python 和 C 语言来编写示例代码,同时也会顺便介绍一下 利用 C 语言扩展 python的方法,最后会给出完整的 C 编写 python 模块的源码。

首先考虑以下应用:假设你需要在项目中实现字符串排序比较的功能,但是事先并不确定应该如何排序(再次假设一下,如果某字符串中如果出现了 “aaa”, "bbb" 这样的子串,就将该字符串排在靠后的位置),此时如果用 C 语言实现了预定义的排序功能,那么万一某天需要改变字符串排序行为,就必须重新编写 C 程序的实现,并且再次编译项目,这样会浪费大量的精力,相反,如果将字符串排序的功能用 python 代码控制,即如何排序由python程序定义,这样将大大提高程序的灵活性。

以下就是示例程序,程序由 python 脚本和 C 编译的 python 模块组成,python 实现字符串比较功能,为了简化期间,本文只是先两个字符串大小的比较(用于说明 python控制程序行为已经足够),程序采用回调函数实现,完整代码如下:

python模块:

/* * ===================================================================================== * *       Filename:  ext.c * *    Description:   * *        Version:  0.1.0 *        Created:  09/16/2011 05:44:40 PM *       Revision:  r1 *       Compiler:  gcc * *         Author:  Fu Haiping 
* Company: ICT * * ===================================================================================== */#include
static PyObject *my_callback = NULL;static PyObject *_set_callback(PyObject *self, PyObject *args){ PyObject *result = NULL; PyObject *temp; if (PyArg_ParseTuple(args, "O", &temp)) { if (!PyCallable_Check(temp)) { PyErr_SetString(PyExc_TypeError, "parameter must be callable"); return NULL; } Py_XINCREF(temp); /* Add a reference to new callback */ Py_XDECREF(my_callback); /* Dispose of previous callback */ my_callback = temp; /* Remember new callback */ /* Boilerplate to return "None" */ Py_INCREF(Py_None); result = Py_None; } return result;}static int _compare(const char *a, const char *b){ long ret; PyObject *arglist; PyObject * result = NULL; arglist = Py_BuildValue("(ss)", a, b); result = PyEval_CallObject(my_callback, arglist); ret = PyInt_AsLong(result); if (result == NULL) return -1; Py_DECREF(result); return ret;}void compare(const char *a, const char *b){ if (_compare(a, b) > 0) { printf("arg1 is greater than arg2\n"); } else if (_compare(a, b) < 0) { printf("arg1 is NOT greater than arg2\n"); } else { printf("arg1 is equal to arg2\n"); }}static PyObject* _compare_callback(PyObject *self, PyObject *args) { const char *a = NULL, *b = NULL; if (!PyArg_ParseTuple(args, "ss", &a, &b)) { return NULL; } compare(a, b); Py_INCREF(Py_None); return Py_None;} static PyMethodDefextMethods[] = { {"setcmp", _set_callback, METH_VARARGS}, {"compare", _compare_callback, METH_VARARGS}, {NULL, NULL}};void initext(){ Py_InitModule("ext", extMethods);}

setup.py 文件:

from distutils.core import setup, Extensionmodule1 = Extension('ext',                    sources = ['ext.c'])setup (name = 'ext',       version = '1.0',       description = 'This is a demo package',       ext_modules = [module1])

执行过程:

$ pythonPython 2.6.6 (r266:84292, Sep 15 2010, 15:52:39) [GCC 4.4.5] on linux2Type "help", "copyright", "credits" or "license" for more information.>>> import ext>>> def compare(a, b):...     if (a > b):...             return -1...     if (a < b):...             return 1...     if (a ==b):...             return 0... >>> setcmp(compare)Traceback (most recent call last):  File "
", line 1, in
NameError: name 'setcmp' is not defined>>> ext.setcmp(compare)>>> ext.compare("aaa", "bbb")arg1 is greater than arg2>>>

上述执行过程中,我们利用了 pythoon 的 compare函数,该函数实现字符串的比较,如果 a > b, 返回 -1,a < b, 返回1,  a == b, 返回0, 这和我们平常的比较方式相反,所以最后的结果中我们可以看到比较 "aaa", "bbb" 时,"aaa" 会比 “bbb” 大。

如果使用 python 定义我们常规的字母排序的比较函数,会看到如下执行结果:

>>> def compare_ex(a, b):...     if (a > b):...             return 1...     if (a < b):...             return -1...     if (a == b):...             return 0... >>> ext.setcmp(compare_ex)>>> ext.compare("aaa", "bbb")arg1 is NOT greater than arg2

此时,"aaa" 就比 "bbb" 小。

结论,以上只是一个小小的尝试,python的灵活性远远不止如此,Haippy会继续探索 python的一些有趣的特性和使用方法,请关注本博客后续文章。:-) 

转载于:https://my.oschina.net/forhappy2010/blog/32437

你可能感兴趣的文章
C# 基于密码的身份验证报错问题System.Net.NetworkCredential
查看>>
GDUT2017校赛:Problem C: 爬楼梯(DP)
查看>>
Heroku
查看>>
前端多个变量指向同一个对象的问题
查看>>
如何让内存使用效率提高
查看>>
2_分布式计算框架MapReduce
查看>>
Axure学习笔记(一)
查看>>
我最钦佩的人
查看>>
java1.5版本之后环境变量的设置
查看>>
BZOJ1412[ZJOI2009]狼和羊的故事——最小割
查看>>
初解禁:供SDK服务端调用函数--02+
查看>>
cnzz流量统计
查看>>
Android 用achartengine 画折线图怎么显示不正确
查看>>
通读AFN②--AFN的上传和下载功能分析、SessionTask及相应的session代理方法的使用细节...
查看>>
11.18日工作总结
查看>>
11.15日个人工作总结
查看>>
PEiD0.95 - 经典查壳工具
查看>>
MySQL中文乱码解决方案
查看>>
JSON对象和字符串之间的相互转换
查看>>
博客目录总纲首页
查看>>