您的位置:首页 > 编程语言 > Python开发

python invoke C program

2010-11-10 15:20 148 查看
zz from http://coolshell.cn/articles/671.html
使用Python的ctypes,我们可以直接调用由C直接编译出来的函数。其实就是调用动态链接库中的函数。为什么我们需要这样做呢,因为有些时候,我们可能需要一个性能上比较讲究的算法,有些时候,我们可以在Python中使用已经有了的现成的被封闭在动态链接库中的函数。下面是如何调用的示例。

首先,我们用一个乘法来表示一个算法功能。下面是C的程序:

int
multiply(int num1, int num2)
{
return num1 * num2;
}


如果在Windows下,你可能需要写成下面这个样子:

#include <windows.h>

BOOL APIENTRY
DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved)
{
return TRUE;
}

__declspec(dllexport)int multiply(int num1, int num2) { return num1 * num2; }


然后,自然是把这个C文件编成动态链接库:

Linux下的编译:

1 gcc -c -fPIC libtest.c
2 gcc -shared libtest.o -o libtest.so

Windows下的编译:1 cl -LD libtest.c -libtest.dll

于是在我们的Python中可以这样使用:
(其中的libtest.so在Windows下改成libtest.dll即可)

>>> from ctypes import *
>>> import os
>>> libtest = cdll.LoadLibrary(os.getcwd() + '/libtest.so')
>>> print libtest.multiply(2, 2)
4


注意:上面的Python脚本中需要把动态链接库放到当前目录中。

--------------------------------------------------------------------------------

zz from http://blog.csdn.net/marising/archive/2008/08/28/2845339.aspx
Python开发效率高,运行效率低。而c/c++恰恰相反。因此在python脚本中调用c/c++的库,对python进行扩展,是很有必要的。使用python api,http://www.python.org/doc/ ,需要安装python-dev。
test.cpp文件如下

#include <python2.6/Python.h> //包含python的头文件
// 1 c/cpp中的函数
int my_c_function(const char *arg) {
int n = system(arg);
return n;
}
// 2 python 包装
static PyObject * wrap_my_c_fun(PyObject *self, PyObject *args) {
const char * command;
int n;
if (!PyArg_ParseTuple(args, "s", &command))//这句是把python的变量args转换成c的变量command
return NULL;
n = my_c_function(command);//调用c的函数
return Py_BuildValue("i", n);//把c的返回值n转换成python的对象
}
// 3 方法列表
static PyMethodDef MyCppMethods[] = {
//MyCppFun1是python中注册的函数名,wrap_my_c_fun是函数指针
{ "MyCppFun1", wrap_my_c_fun, METH_VARARGS, "Execute a shell command." },
{ NULL, NULL, 0, NULL }
};
// 4 模块初始化方法
PyMODINIT_FUNC initMyCppModule(void) {
//初始模块,把MyCppMethods初始到MyCppModule中
PyObject *m = Py_InitModule("MyCppModule", MyCppMethods);
if (m == NULL)
return;
}


make:

g++ -shared -fpic test.cpp -o MyCppModule.so

编译完毕后,目录下会有一个MyCppModule.so文件

test.py文件如下

# -*- coding: utf-8 -*-
import MyCppModule
#导入python的模块(也就是c的模块,注意so文件名是MyCppModule
r = MyCppModule.MyCppFun1("ls -l")
print r
print "OK"


执行

lhb@localhost:~/maplib/clib/pyc/invokec$ python test.py
总计 20
-rwxr-xr-x 1 lhb lhb 45 2010-08-11 17:45 make
-rwxr-xr-x 1 lhb lhb 7361 2010-08-12 10:14 MyCppModule.so
-rw-r--r-- 1 lhb lhb 979 2010-08-11 17:45 test.cpp
-rw-r--r-- 1 lhb lhb 181 2010-08-11 17:45 test.py
0
OK
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: