用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只 ...
随机推荐
- WPF的EventAggregator的发布和订阅
EventAggregator是Prism中专门处理ViewModel与ViewModel之间事件传递的类对象,它提供了针对事件的发布方法和订阅方法,所以可以非常方便的来管理事件.下面分几步来实现相关 ...
- 10 Go 1.10 Release Notes
Go 1.10 Release Notes Introduction to Go 1.10 Changes to the language Ports Tools Default GOROOT &am ...
- Android仿苹果版QQ下拉刷新实现(二) ——贝塞尔曲线开发"鼻涕"下拉粘连效果
前言 接着上一期Android仿苹果版QQ下拉刷新实现(一) ——打造简单平滑的通用下拉刷新控件 的博客开始,同样,在开始前我们先来看一下目标效果: 下面上一下本章需要实现的效果图: 大家看到这个效果 ...
- maven-replacer-plugin 静态资源版本号解决方案(css/js等)
本文介绍如何使用 maven 的 com.google.code.maven-replacer-plugin 插件来自动添加版本号,防止浏览器缓存. 目录 1.解决方案 2.原始文件和最终生成效果 3 ...
- python3脚本获取本机公网ip
python脚本获取本机公网ip 1.获取公网IP地址方式,访问:http://txt.go.sohu.com/ip/soip 2.代码实现 import requests import re r ...
- tqdm:Python 进度条
Tqdm 是 Python 进度条库,可以在 Python 长循环中添加一个进度提示信息.用户只需要封装任意的迭代器,是一个快速.扩展性强的进度条工具库. 用法:tqdm(iterator) 代码地址 ...
- canvas入门级小游戏《开关灯》思路讲解
游戏很简单,10行10列布局,每行每列各10盏灯,游戏初始化时随机点亮其中一些灯,点击某盏灯,其上下左右的灯及本身状态反转,如果点击前是灭着的,点击后即点亮,将所有灯全部点亮才算过关.游戏试玩: 下面 ...
- Codeforces.835E.The penguin's game(交互 按位统计 二分)
题目链接 \(Description\) 有一个长为\(n\)的序列,其中有两个元素为\(y\),其余全为\(x\).你可以进行\(19\)次询问,每次询问你给出一个下标集合,交互库会返回这些元素的异 ...
- 20172319 实验四 《Android程序设计》实验报告
20172319 2018.05.17-30 实验四<Android程序设计> 实验报告 课程名称:<程序设计与数据结构> 学生班级:1723班 学生姓名:唐才铭 学生学号:2 ...
- Nginx简单总结
NGINX简单总结 特点总结 nginx有一个master进程和多个worker进程,master进程是主要用来管理worker进程,管理的内容包括以下内容:接收来自外界的信号,向各个woker进程发 ...