用C扩展python3
来源:互联网 发布:打印机接收数据 不打印 编辑:程序博客网 时间:2024/06/14 22:02
转载自 http://www.cnblogs.com/pengdonglin137/p/6605046.html
官方文档:
https://docs.python.org/3/extending/index.html
- 交叉编译到aarch64上面
以交叉编译到aarch64上面为例,下面是Extest.c的实现:
1 #include <Python.h> 2 #include <stdio.h> 3 #include <stdlib.h> 4 #include <string.h> 5 6 #define BUFSIZE 10 7 8 int fac(int n) { 9 if (n < 2)10 return 1;11 return n * fac(n - 1);12 }13 14 static PyObject * Extest_fac(PyObject *self, PyObject *args) {15 int res;//计算结果值16 int num;//参数17 PyObject* retval;//返回值18 19 //i表示需要传递进来的参数类型为整型,如果是,就赋值给num,如果不是,返回NULL;20 res = PyArg_ParseTuple(args, "i", &num);21 if (!res) {22 //包装函数返回NULL,就会在Python调用中产生一个TypeError的异常23 return NULL;24 }25 res = fac(num);26 //需要把c中计算的结果转成python对象,i代表整数对象类型。27 retval = (PyObject *)Py_BuildValue("i", res);28 return retval;29 }30 31 char *reverse(char *s) {32 register char t;33 char *p = s;34 char *q = (s + (strlen(s) - 1));35 while (p < q) {36 t = *p;37 *p++ = *q;38 *q-- = t;39 }40 return s;41 }42 43 static PyObject *44 Extest_reverse(PyObject *self, PyObject *args) {45 char *orignal;46 if (!(PyArg_ParseTuple(args, "s", &orignal))) {47 return NULL;48 }49 return (PyObject *)Py_BuildValue("s", reverse(orignal));50 }51 52 static PyObject *53 Extest_doppel(PyObject *self, PyObject *args) {54 char *orignal;55 char *reversed;56 PyObject * retval;57 if (!(PyArg_ParseTuple(args, "s", &orignal))) {58 return NULL;59 }60 retval = (PyObject *)Py_BuildValue("ss", orignal, reversed=reverse(strdup(orignal)));61 free(reversed);62 return retval;63 }64 65 static PyMethodDef66 ExtestMethods[] = {67 {"fac", Extest_fac, METH_VARARGS},68 {"doppel", Extest_doppel, METH_VARARGS},69 {"reverse", Extest_reverse, METH_VARARGS},70 {NULL, NULL},71 };72 73 static struct PyModuleDef ExtestModule = {74 PyModuleDef_HEAD_INIT,75 "Extest",76 NULL,77 -1,78 ExtestMethods79 };80 81 PyMODINIT_FUNC PyInit_Extest(void)82 {83 return PyModule_Create(&ExtestModule);84 }
采用手动编译, Makefile如下:
1 CFLAGS = -pthread -fno-strict-aliasing -g -O2 -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes 2 CFLAGS += -fPIC -I /home/pengdonglin/src/qemu/python_cross_compile/Python3/aarch64/include/python3.6m 3 CC = /home/pengdonglin/src/qemu/aarch64/gcc-linaro-aarch64-linux-gnu-4.9-2014.07_linux/bin/aarch64-linux-gnu-gcc 4 5 all:Extest.so 6 7 Extest.o: Extest.c 8 $(CC) $(CFLAGS) -c $^ -o $@ 9 10 Extest.so: Extest.o11 $(CC) -pthread -shared $^ -o $@12 cp $@ /home/pengdonglin/src/qemu/python_cross_compile/Python3/aarch64/lib/python3.6/site-packages/13 14 clean:15 $(RM) *.o *.so16 17 .PHONY: clean all
执行make命令,就会在当前目录下生成一个Extest.so文件,然后将其放到板子上面的/usr/lib/python3.6/site-packages/下面即可
测试:
1 [root@aarch64 root]# cp /mnt/Extest.so /usr/lib/python3.6/site-packages/ 2 [root@aarch64 root]# python3 3 Python 3.6.0 (default, Mar 23 2017, 10:54:13) 4 [GCC 4.9.1 20140529 (prerelease)] on linux 5 Type "help", "copyright", "credits" or "license" for more information. 6 >>> import Extest 7 >>> Extest.fac(4) 8 24 9 >>> Extest.reverse("pengdonglin")10 'nilgnodgnep'11 >>> Extest.doppel("pengdonglin")12 ('pengdonglin', 'nilgnodgnep')
- 编译到x86_64上面
编写setup.py如下:
1 #/usr/bin/env python32 3 from distutils.core import setup, Extension4 5 MOD = 'Extest'6 setup(name=MOD, ext_modules=[Extension(MOD, sources=['Extest.c'])])
编译
1 $/usr/local/bin/python3 ./setup.py build2 running build3 running build_ext4 building 'Extest' extension5 creating build6 creating build/temp.linux-x86_64-3.67 gcc -pthread -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -fPIC -I/usr/local/include/python3.6m -c Extest.c -o build/temp.linux-x86_64-3.6/Extest.o8 creating build/lib.linux-x86_64-3.69 gcc -pthread -shared build/temp.linux-x86_64-3.6/Extest.o -o build/lib.linux-x86_64-3.6/Extest.cpython-36m-x86_64-linux-gnu.so
可以看到,在Python3上面用setup.py默认生成的so的名字是Extest.cpython-36m-x86_64-linux-gnu.so
安装
1 $sudo /usr/local/bin/python3 ./setup.py install2 [sudo] password for pengdonglin: 3 running install4 running build5 running build_ext6 running install_lib7 copying build/lib.linux-x86_64-3.6/Extest.cpython-36m-x86_64-linux-gnu.so -> /usr/local/lib/python3.6/site-packages8 running install_egg_info9 Writing /usr/local/lib/python3.6/site-packages/Extest-0.0.0-py3.6.egg-info
可以看到,将Extest.cpython-36m-x86_64-linux-gnu.so拷贝到了/usr/local/lib/python3.6/site-packages下面。
测试
在PC上面输入python3命令:
1 $python3 2 Python 3.6.0 (default, Mar 23 2017, 10:40:28) 3 [GCC 4.8.4] on linux 4 Type "help", "copyright", "credits" or "license" for more information. 5 >>> import Extest 6 >>> Extest 7 <module 'Extest' from '/usr/local/lib/python3.6/site-packages/Extest.cpython-36m-x86_64-linux-gnu.so'> 8 >>> Extest.fac(4) 9 2410 >>> Extest.reverse("pengdonglin")11 'nilgnodgnep'12 >>> Extest.doppel("pengdonglin")13 ('pengdonglin', 'nilgnodgnep')14 >>>
可以在第7行看到加载的Extest.so的路径,而且我们只需要import Extest就可以了。
完。
阅读全文
0 0
- 用C扩展python3
- Python3 C扩展
- python3.6借助vs2017扩展c
- VS2013 Python3.5.3 编写C扩展库
- 使用vs2008实现C语言对Python3的扩展
- Python的C扩展模块的编写(Anaconda+VS2013,python3.5和c++)
- 用C扩展php
- 用c扩展python
- Python3.52安装扩展错误
- python3.5之扩展模块
- 用C#创建SHELL扩展
- 用C/C++扩展Python
- 用C语言扩展perl
- 自己动手用 C 扩展 PHP
- 自己动手用 C 扩展 PHP
- 用C/C++扩展Python
- 用C扩展PHP[转]
- [原]用C扩展python
- Android面试之简历篇
- 括号序列匹配问题
- ServletContext && ServletContextListen 的用法案例-->统计网站访问量
- 一篇文章轻松搞懂原型对象和原型链
- 《Python核心编程(第2版)》读书笔记(4)之浅拷贝、深拷贝(关键词:Python/浅拷贝/深拷贝)
- 用C扩展python3
- 尺取法的应用
- 让光模块写码变得“so Easy!”
- Servlet 生命周期、工作原理
- Java基础总结
- 函数返回值和函数
- 2017 ACM-ICPC 亚洲区(乌鲁木齐赛区) A. Banana
- sprintf()函数
- 隐藏功能之番外篇