使用C/C++代码编写Python模块
假如我们要用C语言实现下面的python脚本bird.py
import os
def fly(name):
print(name + " is flying.\n")
调用脚本main.py
import bird
bird.fly("fwd")
执行效果如下
> python main.py
fwd is flying.
实现相同逻辑的原始C代码bird.c
#include <stdio.h>
void fly(const char *name)
{
printf("%s is flying.\n", name);
}
下面我们要将原始C代码改造成可以被main.py的python模块:
- 包含头文件Python.h
- 添加C函数fly的Python调用版本bird_fly
- 添加向Python呈现C函数的方法表bird_methods
- 添加模块初始化函数initbird(当动态库被python解释器搜索到时调用的函数)
#include <Python.h>
#include <stdio.h>
void fly(const char *name)
{
printf("%s is flying.\n", name);
}
static PyObject *bird_fly(PyObject *self, PyObject *args)
{
const char *name;
if (!PyArg_ParseTuple(args, "s", &name))
return NULL;
fly(name);
Py_INCREF(Py_None);
return Py_None;
}
static PyMethodDef bird_methods[] = {
{ "fly", bird_fly, METH_VARARGS, "Bird fly" },
{ NULL, NULL, 0, NULL }
};
PyMODINIT_FUNC initbird(void)
{
PyImport_AddModule("bird");
Py_InitModule("bird", bird_methods);
}
Linux下编译
# yum install -y python-devel
# gcc -o bird.so `python-config --cflags` `python-config --libs` -shared bird.c
### 将main.py和bird.so放置在同一目录下
# python main.py
fwd is flying.
Windows下编译
VS2017(只需安装python2.7的64位版本即可,本地开发工具可不装)下创建空项目bird,然后添加源文件bird.cpp(内容同bird.c),项目配置如下:
| Tab | 属性 | 值 |
|---|---|---|
| 常规 | 常规 > 目标名称 | 将此字段设置为与 Python 看到的模块名称完全匹配。 |
| 常规 | 常规 > 目标扩展名 | .pyd |
| 常规 | 项目默认值 > 配置类型 | 动态库(.dll) |
| C/C++ > 常规 | 附加包含目录 | 根据相应的安装添加 Python include 文件夹,例如 C:\Python27amd64\include |
| C/C++ > 预处理器 | 预处理器定义 | 在字符串的开头添加 Py_LIMITED_API;,可限制可从 Python 调用的某些函数,并使代码在 Python 不同版本之间更易于移植。 |
| C/C++ > 代码生成 | 运行库 | 多线程 DLL (/MD)(请参阅下面的“警告”) |
| 链接器 > 常规 | 附加库目录 | 根据相应的安装添加包含 .lib 文件的 Python libs 文件夹,例如 C:\Python27amd64\libs。 (务必指向包含 .lib文件的 libs 文件夹,而非包含 .py 文件的 Lib 文件夹。) |
### 记住选择release + x64编译模式,否则编译dll会报错,然后将main.py和bird.pyd放置在同一目录下
bird\x64\Release> python main.py
fwd is flying.
参考文档
使用C/C++代码编写Python模块的更多相关文章
- VS2012 编译带有c/c++代码的python模块失败解决方案
python2.7默认编译带有/c++代码的模块/包是使用VS2008环境变量,所以为了可用,我们要在编译前设置环境变量 SET VS90COMNTOOLS=%VS110COMNTOOLS% 但有时只 ...
- 扩展Python模块系列(一)----开发环境配置
本系列将介绍如何用C/C++扩展Python模块,使用C语言编写Python模块,添加到Python中作为一个built-in模块.Python与C之间的交互目前有几种方案: 1. 原生的Python ...
- 编写高质量代码--改善python程序的建议(八)
原文发表在我的博客主页,转载请注明出处! 建议四十一:一般情况下使用ElementTree解析XML python中解析XML文件最广为人知的两个模块是xml.dom.minidom和xml.sax, ...
- python模块之sys和subprocess以及编写简单的主机扫描脚本
python模块之sys和subprocess以及编写简单的主机扫描脚本 1.sys模块 sys.exit(n) 作用:执行到主程序末尾,解释器自动退出,但是如果需要中途退出程序,可以调用sys.e ...
- Python代码编写规范
Python代码编写规范 编码: a) 如无特殊情况,文件一律使用UTF-8编码 b) 如无需特殊情况,文件头部必须加入#-*-coding:utf-8-*- 缩进 a) 统一 ...
- python的单元测试代码编写流程
单元测试: 单元测试是对单独的代码块分别进行测试, 以确保它们的正确性, 单元测试主要还是由开发人员来做, 其余的集成测试和系统测试由专业的测试人员来做. python的单元测试代码编写主要记住以下几 ...
- 编写高质量代码--改善python程序的建议(七)
原文发表在我的博客主页,转载请注明出处! 建议三十四:掌握字符串的基本用法 编程有两件事,一件是处理数值,另一件是处理字符串,在商业应用编程来说,处理字符串的代码超过八成,所以需要重点掌握. 首先有个 ...
- 编写高质量代码--改善python程序的建议(四)
原文发表在我的博客主页,转载请注明出处! 建议十八:有节制的使用from...import语句 python提供了三种方式引入外部模块: import语句 from...import... __imp ...
- 编写高质量代码--改善python程序的建议(三)
原文发表在我的博客主页,转载请注明出处! 建议十三:警惕eval()的安全漏洞 相信经常处理文本数据的同学对eval()一定是欲罢不能,他的使用非常简单: eval("1+1==2" ...
随机推荐
- Protege4.3使用入门(二)
1.支持OWLViz 利用OWLViz查看我们构建Class的结构图.如果尚未安装,请到http://www.graphviz.org/pub/graphviz/stable/windows/grap ...
- oracle——存储过程参数
oracle 存储过程类型: 1.in:输入类型,即由应用程序将数据传入oracle存储过程中:这种参数在存储过程中是只读参数,在存储过程中无法对该类型的参数进行修改: 2.out:输出参数,是在存储 ...
- Python基础学习五 内置模块
time 模块 1 >>> import time 2 >>> time.time() 3 1491064723.808669 4 >>> # t ...
- OK6410之tftp下载内核,nfs…
原文地址:OK6410之tftp下载内核,nfs挂载文件系统全过程详解[转]作者:千山我独行 由于工作的平台也是嵌入式,差不多的平台,所以一直就没有把自己买过来的ok6410板子好好玩玩.以前一直都是 ...
- C#中查询字符串中是否包含指定字符/串,使用IndexOf还是Contains?
C#中查询字符串中是否包含指定字符/串,使用IndexOf还是Contains?这是一个很常见的命题,以前也没有注意,今天QQ群里有人提起,于是就做了下试验,代码如下: using System; u ...
- Python函数之返回值、作用域和局部变量
一.函数返回值 说到返回值,相信大家肯定都认识,没错,就是return. 所谓返回值可以这样理解:函数外部的代码要想获取函数的执行结果,就可以在函数里用return语句把结果返回. 那具体怎么用呢?接 ...
- java基础之JDBC五:批处理简单示例
/** * 批处理 * 批处理跟事务不同 只是把一批sql放到一起执行 2条sql是可以一条执行成功 一条执行失败 是不可逆的 */ public class Test { public static ...
- 算法技巧讲解》关于对于递推形DP的前缀和优化
这是在2016在长沙集训的第三天,一位学长讲解了“前缀和优化”这一技巧,并且他这一方法用的很6,个人觉得很有学习的必要. 这一技巧能使线性递推形DP的速度有着飞跃性的提升,从O(N2)优化到O(N)也 ...
- C#连接Mysql数据库 MysqlHelper.cs文件
mysql.data.dll下载_c#连接mysql必要插件mysql.data.dll是C#操作MYSQL的驱动文件,是c#连接mysql必要插件,使c#语言更简洁的操作mysql数据库.当你的电脑 ...
- 使用clr 调用C#编写的dll中的方法的全解释
使用clr 调用C#编写的dll中的方法的全解释1.数据库初始化:将下面这段代码直接在运行就可以初始化数据库了exec sp_configure 'show advanced options', '1 ...