用C扩展Python3
官方文档:
https://docs.python.org/3/extending/index.html
- 交叉编译到aarch64上面
以交叉编译到aarch64上面为例,下面是Extest.c的实现:
#include <Python.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h> #define BUFSIZE 10 int fac(int n) {
if (n < )
return ;
return n * fac(n - );
} static PyObject * Extest_fac(PyObject *self, PyObject *args) {
int res;//计算结果值
int num;//参数
PyObject* retval;//返回值 //i表示需要传递进来的参数类型为整型,如果是,就赋值给num,如果不是,返回NULL;
res = PyArg_ParseTuple(args, "i", &num);
if (!res) {
//包装函数返回NULL,就会在Python调用中产生一个TypeError的异常
return NULL;
}
res = fac(num);
//需要把c中计算的结果转成python对象,i代表整数对象类型。
retval = (PyObject *)Py_BuildValue("i", res);
return retval;
} char *reverse(char *s) {
register char t;
char *p = s;
char *q = (s + (strlen(s) - ));
while (p < q) {
t = *p;
*p++ = *q;
*q-- = t;
}
return s;
} static PyObject *
Extest_reverse(PyObject *self, PyObject *args) {
char *orignal;
if (!(PyArg_ParseTuple(args, "s", &orignal))) {
return NULL;
}
return (PyObject *)Py_BuildValue("s", reverse(orignal));
} static PyObject *
Extest_doppel(PyObject *self, PyObject *args) {
char *orignal;
char *reversed;
PyObject * retval;
if (!(PyArg_ParseTuple(args, "s", &orignal))) {
return NULL;
}
retval = (PyObject *)Py_BuildValue("ss", orignal, reversed=reverse(strdup(orignal)));
free(reversed);
return retval;
} static PyMethodDef
ExtestMethods[] = {
{"fac", Extest_fac, METH_VARARGS},
{"doppel", Extest_doppel, METH_VARARGS},
{"reverse", Extest_reverse, METH_VARARGS},
{NULL, NULL},
}; static struct PyModuleDef ExtestModule = {
PyModuleDef_HEAD_INIT,
"Extest",
NULL,
-,
ExtestMethods
}; PyMODINIT_FUNC PyInit_Extest(void)
{
return PyModule_Create(&ExtestModule);
}
采用手动编译, Makefile如下:
CFLAGS = -pthread -fno-strict-aliasing -g -O2 -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes
CFLAGS += -fPIC -I /home/pengdonglin/src/qemu/python_cross_compile/Python3/aarch64/include/python3.6m
CC = /home/pengdonglin/src/qemu/aarch64/gcc-linaro-aarch64-linux-gnu-4.9-.07_linux/bin/aarch64-linux-gnu-gcc all:Extest.so Extest.o: Extest.c
$(CC) $(CFLAGS) -c $^ -o $@ Extest.so: Extest.o
$(CC) -pthread -shared $^ -o $@
cp $@ /home/pengdonglin/src/qemu/python_cross_compile/Python3/aarch64/lib/python3./site-packages/ clean:
$(RM) *.o *.so .PHONY: clean all
执行make命令,就会在当前目录下生成一个Extest.so文件,然后将其放到板子上面的/usr/lib/python3.6/site-packages/下面即可
测试:
[root@aarch64 root]# cp /mnt/Extest.so /usr/lib/python3./site-packages/
[root@aarch64 root]# python3
Python 3.6. (default, Mar , ::)
[GCC 4.9. (prerelease)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import Extest
>>> Extest.fac() >>> Extest.reverse("pengdonglin")
'nilgnodgnep'
>>> Extest.doppel("pengdonglin")
('pengdonglin', 'nilgnodgnep')
- 编译到x86_64上面
编写setup.py如下:
#/usr/bin/env python3 from distutils.core import setup, Extension MOD = 'Extest'
setup(name=MOD, ext_modules=[Extension(MOD, sources=['Extest.c'])])
编译
$/usr/local/bin/python3 ./setup.py build
running build
running build_ext
building 'Extest' extension
creating build
creating build/temp.linux-x86_64-3.6
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.o
creating build/lib.linux-x86_64-3.6
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
安装
$sudo /usr/local/bin/python3 ./setup.py install
[sudo] password for pengdonglin:
running install
running build
running build_ext
running install_lib
copying build/lib.linux-x86_64-3.6/Extest.cpython-36m-x86_64-linux-gnu.so -> /usr/local/lib/python3./site-packages
running install_egg_info
Writing /usr/local/lib/python3./site-packages/Extest-0.0.-py3..egg-info
可以看到,将Extest.cpython-36m-x86_64-linux-gnu.so拷贝到了/usr/local/lib/python3.6/site-packages下面。
测试
在PC上面输入python3命令:
$python3
Python 3.6. (default, Mar , ::)
[GCC 4.8.] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import Extest
>>> Extest
<module 'Extest' from '/usr/local/lib/python3.6/site-packages/Extest.cpython-36m-x86_64-linux-gnu.so'>
>>> Extest.fac() >>> Extest.reverse("pengdonglin")
'nilgnodgnep'
>>> Extest.doppel("pengdonglin")
('pengdonglin', 'nilgnodgnep')
>>>
可以在第7行看到加载的Extest.so的路径,而且我们只需要import Extest就可以了。
完。
用C扩展Python3的更多相关文章
- 使用C语言扩展Python3
使用C语言扩展Python3.在Python3中正确调用C函数. 1. 文件demo.c #include <Python.h> // c function static PyObject ...
- python3.5之mysql扩展
最近在学习廖雪峰的python3的教程,这是官方http://www.liaoxuefeng.com/,建议大家想学习python的同学可以去看看,真的是在网上能找到的最好文本教程,没有之一 在廖老实 ...
- 在python3中安装mysql扩展,No module named 'ConfigParser'
在python2.7中,我们安装的是 MySqldb或这 MySQL-python,能够正却安装,但在python3中,由于 其使用的扩展 ConfigParser 已经改名为 configpars ...
- Python3 与 C# 扩展之~模块专栏
代码裤子:https://github.com/lotapp/BaseCode/tree/maste 在线编程:https://mybinder.org/v2/gh/lotapp/BaseCode ...
- Python3 与 C# 扩展之~基础衍生
本文适应人群:C# or Python3 基础巩固 代码裤子: https://github.com/lotapp/BaseCode 在线编程: https://mybinder.org/v2/g ...
- Python3 与 C# 扩展之~基础拓展
上次知识回顾:https://www.cnblogs.com/dotnetcrazy/p/9278573.html 代码裤子:https://github.com/lotapp/BaseCode ...
- python3.4学习笔记(三) idle 清屏扩展插件
python3.4学习笔记(三) idle 清屏扩展插件python idle 清屏问题的解决,使用python idle都会遇到一个常见而又懊恼的问题——要怎么清屏?在stackoverflow看到 ...
- Python3.x:python: extend (扩展) 与 append (追加) 的区别
Python3.x:python: extend (扩展) 与 append (追加) 的区别 1,区别: append() 方法向列表的尾部添加一个新的元素.只接受一个参数: extend()方法只 ...
- python3.x 匿名函数lambda_扩展sort
#匿名函数lambda 参数: 表达式关键字 lambda 说明它是一个匿名函数,冒号 : 前面的变量是该匿名函数的参数,冒号后面是函数的返回值,注意这里不需使用 return 关键字. ambda只 ...
随机推荐
- Insert Interval & Merge Intervals
Insert Intervals Given a non-overlapping interval list which is sorted by start point. Insert a new ...
- mysql主键的缺少导致备库hang
最近线上频繁的出现slave延时的情况,经排查发现为用户在删除数据的时候,由于表主键的主键的缺少,同时删除条件没有索引,或或者删除的条件过滤性极差,导致slave出现hang住,严重的影响了生产环境的 ...
- c# 获取百度最后的url
using System;using System.Collections.Generic;using System.Linq;using System.Net.Http;using System.T ...
- 『实践』VirtualBox 5.1.18+Centos 6.8+hadoop 2.7.3搭建hadoop完全分布式集群及基于HDFS的网盘实现
『实践』VirtualBox 5.1.18+Centos 6.8+hadoop 2.7.3搭建hadoop完全分布式集群及基于HDFS的网盘实现 1.基本设定和软件版本 主机名 ip 对应角色 mas ...
- js 替换任意字符串中间几位为*星号
<script> var str='河南纳智企业管理咨询有限公司'; a=str.substr(0,2)+'***'+str.substr(5,str.split('').length); ...
- Python常见面试(习题)——水仙花数
今天,给大家分享一个习题. 用python输出100到1000以内的水仙花数. 相信很多小伙伴都听到过,或者遇到过这个题目. 那么今天就来带大家做一做这道题. 首先,我们要知道什么是水仙花数, (@_ ...
- UFLDL 教程学习笔记(一)
ufdl的新教程,从基础学起.第一节讲的是线性回归.主要目的是熟悉目标函数,计算梯度和优化. 按着教程写完代码后,总是编译出错,一查是mex的原因,实在不想整了. 这位博主用的是向量,比较简洁:htt ...
- java 异常历史 和观点
异常起源于PL/1和Mesa之类的系统中. 1.) 不在于编译器是否会强制程序员去处理错误,而是要由一致的,使用异常来报告错误 2.) 不在于什么时候进行检查,而是一定要有检查.
- CF1064B 【Equations of Mathematical Magic】
题目要求解$a-(a\oplus x)-x=0$的解$x$的个数 移项得$a-x=a\oplus x$ $a$的二进制形式,应该是一个$01$串,异或的过程是不能影响到两个不同的位的,所以我们按位考虑 ...
- 026 Spark 的官网(版本为1.6.1的总官网)
1. 多多读官网,所有的只知识点都可以从上面的总纲中查到.