使用Python可以快速的搭建软件原型和框架,但是在对性能要求比较严格的地方,就需要使用C/C++扩展来提高性能。或是在需要对底层的硬件进行操作的时候就必须使用C语言了。
C/C++模块需要使用进行封装,然后编译成动态链接库的形式供Python导入调用,步骤:
例如一个C文件(hello.c)需要导入到Python中使用:
- #include <stdio.h>
- void test(void)
- {
- fprintf(stdout, "Hello C\n");
- return;
- }
方法1:手工编译链接
- 编写"hello.i"接口文件,%module之后跟随模块的名称,%{和%}之间放置包含的头文件,然后在后面跟随函数的声明,详细的内容参考
- %module hello
- %{
- #include
- %}
- extern void test(void);
- 使用SWIG生成包裹文件
- 使用swig命令之后会生成"hello.py"和"hello_wrap.c"这两个文件
- 编译C文件和包裹文件(需要知道python在系统中的安装路径)
- gcc -c hello.c
- gcc -I /usr/include/python2.6 -c hello_wrap.c
以上命令是在Linux环境中使用GCC编译的,在其他系统中也类似
- 将C文件和包裹文件编译成动态链接库,得到动态链接库文件"_hello.so"
- gcc -shared hello.o hello_wrap.o -o _hello.so
方法2:使用Distutils编译扩展
- from distutils.core import setup, Extension
- setup(name='hello', version='1.0', ext_modules = [Extension('_hello', ['hello.c', 'hello.i'])])
Extension中第一个参数的名字就是下一步生成的动态链接库所使用的名字"_hello.so"
- 编译扩展得到Python可以使用的动态链接库文件"_hello.so"
- python setup.py build_ext --inplace
通过以上提供的2种方法都可以得到一个 Linux动态链接库“so”文件,将得到的"_hello.so"模块放在当前目录中既可以在python命令行中进行测试例如:
- Python 2.6.6 (r266:84292, Dec 27 2010, 00:02:40)
- [GCC 4.4.5] on linux2
- Type "help", "copyright", "credits" or "license" for more information.
- >>> import _hello as c_test
- >>> c_test.test()
- Hello C
- >>>
注意:生成的动态链接库的名字要以接口文件(*.i)中的%module中的名字之前加“_”来生成,如例子中模块的名字为“hello”那么生成的动态链接库的名字要为“_hello.so”否则在python中导入的时候会报错:“ImportError: dynamic module does not define init function (inithello)”这是因为在导入之后要调用初始化函数,而初始化函数的名字命名格式是“init_modulename”
[参考]:
《Python 基础教程》17章扩展Python、18章打包
阅读(2719) | 评论(0) | 转发(0) |