python的C扩展调用,使用原生的python-C-Api
1、在文件第一行包含python调用扩展的头文件
#include <Python.h>
2、用原生C写好需要调用的函数
int add_one(int a){
return a + ;
}
3、用python规定的调用方式,加一层C语言的包装,包装内容包括
a.定义一个新的静态函数,接受两个PyObject *参数,返回一个PyObject *值
b.解析第二个输入的PyObject *(通过PyArg_ParseTuple等方法),把python输入的变量变成C的变量
c.调用原生C函数
d.将调用返回的C变量,转换为PyObject*或其子类(通过PyLong_FromLong)等方法,并返回
static PyObject * py_add_one(PyObject *self, PyObject *args){
int num;
if (!PyArg_ParseTuple(args, "i", &num)) return NULL;
return PyLong_FromLong(add_one(num));
}
4、创建一个数组,来指明python可调用这个扩展的函数。
其中"add_one",代表编译后python调用时希望使用的函数名,
py_add_one,代表调用当前C代码中的哪个函数,
METH_VARARGS,代表函数的参数传递形式,主要包括位置参数和关键字参数两种,
关于这个变量具体参考https://docs.python.org/3/extending/extending.html的1.4节。
如果希望添加新的函数,则在最后的{NULL, NULL}之前按同样格式填写新的调用信息。
static PyMethodDef Methods[] = {
{"add_one", py_add_one, METH_VARARGS},
{NULL, NULL}
};
5、创建module的信息,包括了python调用时的模块名、可调用的函数集(就是上一步定义的Methods)等信息
static struct PyModuleDef cModule = {
PyModuleDef_HEAD_INIT,
"Test", /*module name*/
"", /* module documentation, may be NULL */
-, /* size of per-interpreter state of the module, or -1 if the module keeps state in global variables. */
Methods
};
6、module初始化
PyMODINIT_FUNC PyInit_Test(void){ return PyModule_Create(&cModule);}
7、写一个setup.py脚本,使用distutils包作为包构建安装的工具
from distutils.core import setup, Extension
module1 = Extension('Test', sources = ['add.c'])
setup (name = 'Test',
version = '1.0',
description = 'This is a demo package',
ext_modules = [module1])
8、调用setup.py,python setup.py build可以编译代码,python setup.py install可以编译代码并直接将包放入当前python环境的包的路径以供调用。
非常需要注意的是,python 3.5版本以后,windows平台下python的C/C++扩展不再支持gcc的编译,并强制要求使用msvc进行编译
所以python setup.py build编译出来的结果无法正常使用,需使用
python setup.py build --compiler msvc
当需要安装时,则
python setup.py build --compiler msvc install
关于此情况的参考:
https://stackoverflow.com/questions/16737260/how-to-tell-distutils-to-use-gcc
https://stackoverflow.com/questions/3297254/how-to-use-mingws-gcc-compiler-when-installing-python-package-using-pip
9、测试安装好的C扩展
import Test as t
x = 1
print(t.add_one(x))
附C文件完整代码
#include <Python.h>
int add_one(int a){
return a + ;
}
static PyObject * py_add_one(PyObject *self, PyObject *args){
int num;
if (!PyArg_ParseTuple(args, "i", &num)) return NULL;
return PyLong_FromLong(add_one(num));
}
static PyMethodDef Methods[] = {
{"add_one", py_add_one, METH_VARARGS},
{NULL, NULL}
};
static struct PyModuleDef cModule = {
PyModuleDef_HEAD_INIT,
"Test", /*module name*/
"", /* module documentation, may be NULL */
-, /* size of per-interpreter state of the module, or -1 if the module keeps state in global variables. */
Methods
};
PyMODINIT_FUNC PyInit_Test(void){ return PyModule_Create(&cModule);}
https://segmentfault.com/a/1190000000479951
python的C扩展调用,使用原生的python-C-Api的更多相关文章
- python获取文件扩展名的方法(转)
主要介绍了python获取文件扩展名的方法,涉及Python针对文件路径的相关操作技巧.具体实现方法如下: 1 2 3 4 import os.path def file_extension(path ...
- python获取文件扩展名的方法
主要介绍了python获取文件扩展名的方法,涉及Python针对文件路径的相关操作技巧 import os.path def file_extension(path): ] print file_ex ...
- python使用C扩展
CPython还为开发者实现了一个有趣的特性,使用Python可以轻松调用C代码 开发者有三种方法可以在自己的Python代码中来调用C编写的函数-ctypes,SWIG,Python/C API.每 ...
- Python与Javascript相互调用超详细讲解(2022年1月最新)(三)基本原理Part 3 - 通过C/C++联通
目录 TL; DR python调javascript javascript调python 原理 基于Node.js的javascript调用python 从Node调用python函数 V8 嵌入P ...
- python与c互相调用
虽然python开发效率很高,但作为脚本语言,其性能不高,所以为了兼顾开发效率和性能,通常把性能要求高的模块用c或c++来实现或者在c或c++中运行python脚本来处理逻辑,前者通常是python中 ...
- paip.java c# .net php python调用c++ c dll so windows api 总结
paip.java c# .net php python调用c++ c dll so windows api 总结 作者Attilax 艾龙, EMAIL:1466519819@qq.com 来 ...
- Python 的 JPype 模块调用 Jar 包
背景与需求 最近学习并安装使用了HttpRunner框架去尝试做接口测试,并有后续在公司推广的打算. HttpRunner由Python开发,调用接口时需要依赖Python:而大多数公司的扩展工具包使 ...
- [转] C++ 和 python之间的互相调用
转载自:https://www.cnblogs.com/apexchu/p/5015961.html 一.Python调用C/C++ 1.Python调用C动态链接库 Python调用C库比较简单,不 ...
- (转载)Python 的 JPype 模块调用 Jar 包
Python 的 JPype 模块调用 Jar 包 背景与需求 最近学习并安装使用了HttpRunner框架去尝试做接口测试,并有后续在公司推广的打算. HttpRunner由Python开发,调用接 ...
随机推荐
- Python-多任务复制文件夹
import multiprocessing import os import time def copy_file(queue, file_name, old_folder_name, new_fo ...
- python的IO
格式化输出 格式化输出是指通过print()等函数向指定的地方(比如屏幕)输出指定格式的内容 格式: age = 18 name = "xiaohua" print("我 ...
- Flash Builder 使用
1. 解决编译慢的问题:用记事本打开安装目录下的 FlashBuilder.ini ,将里面设置的容量都扩大一半,如-Xms256m改为 -Xms512m,另外几项类似修改: 定位到相应版本的sdks ...
- Java 原子类 java.util.concurrent.atomic
Java 原子类 java.util.concurrent.atomic 1.i++为什么是非线程安全的 i++其实是分为3个步骤:获取i的值, 把i+1, 把i+1的结果赋给i 如果多线程执行i++ ...
- 阿里云服务器上搭建seafile专业版
因为官方一键安装教程在阿里云服务器上无法安装,由于水平有限,无法解决,所以选择手动安装 参考资料: 1,.腾讯云搭建seafile服务器 2.How to Install Seafile with N ...
- Python-控制语句及函数
if-elif-else for while 函数 函数定义 空函数 pass 返回多个值 可变参数 * 关键字参数 ** 控制语句 if - elif - else 比如,输入用户年龄,根据年龄打印 ...
- Python sys.path详解
如何将路径“永久"添加到sys.path? sys.path是python的搜索模块的路径集,是一个list ['', 'C:\\WINDOWS\\system32\\python26.zi ...
- (转载)SVN使用说明
为了方便个人使用,转载过来的,如需查阅,请前往原文地址:http://blog.csdn.net/ideal_utopia/article/details/51883796 为什么要使用SVN? 在程 ...
- 神州优车挂牌新三板!专车B2C对决C2C将愈发狂暴?
近日,全国中小企业股份转让系统公告显示,神州优车已获准在新三板挂牌.神州优车作为神州专车的主营主体,此次挂牌新三板意味着神舟专车成功突围,成为"专车第一股".相比滴滴.Uber中国 ...
- 有了这个开源 Java 项目,开发出炫酷的小游戏好像不难?
本文适合有 Java 基础知识的人群,跟着本文可学习和运行 Java 的游戏. 本文作者:HelloGitHub-秦人 HelloGitHub 推出的<讲解开源项目>系列,今天给大家带来一 ...