Loading [MathJax]/jax/input/TeX/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >python swig 调用C/C++接口

python swig 调用C/C++接口

作者头像
用户5760343
发布于 2022-05-13 00:42:00
发布于 2022-05-13 00:42:00
8630
举报
文章被收录于专栏:sktjsktj

当你觉得python慢的时候,当你的c/c++代码难以用在python上的时候,你可能会注意这篇文章。swig是一个可以把c/c++代码封装为python库的工具。(本文封装为python3的库)

文章结构

  • 整体看封装
  • 只使用python提供的c语言接口(Python.h)封装一个简单的c函数
  • 使用swig封装一个简单的c函数
  • 使用swig封装一个简单的c++类

整体看封装

c/c++实现功能 ==> c/c++封装c/c++函数 ==> 将前两者编译生成动态库 ==> python进一步封装;

手动封装c函数

我把实现和封装放在一个文件中(add.c)。

[

复制代码

](javascript:void(0); "复制代码")

<pre style="margin: 0px; padding: 0px; white-space: pre-wrap; overflow-wrap: break-word; font-family: "Courier New" !important; font-size: 12px !important;">//add.c

include <Python.h>

//定义一个C函数 int add(int a,int b){ return a+b; } //包装c函数 static PyObject* _add_add(PyObject self,PyObject args){ int a,b; PyArg_ParseTuple(args,"ii",&a,&b); //把python参数转换为c函数 return (PyObject)Py_BuildValue("i",add(a,b)); //返回python对象的指针 } //方法结构数组 static PyMethodDef _addMethods[]={ // { "add",_add_add,METH_VARARGS}, {NULL,NULL} }; //模块结构 static struct PyModuleDef _addModule={ PyModuleDef_HEAD_INIT, "_add", //模块名 "ADD", //文档 -1, _addMethods //PyMethodsDef实例 }; //初始化函数 PyMODINIT_FUNC PyInit__add(){ PyModule_Create(&_addModule); //参数为PyModuleDef } /*************************************************

  • (1)定义一个C函数,如add()。
  • (2)包装c函数,如_add_add()。
  • (3)方法结构数组,如_addMethods[]。
  • (4)模块结构,如_addModule。
  • (5)初始化函数PyInit_<module_name>(),如PyInit__add(),"_add"是模块名。
  • 联系:
  • import ==> PyInit_<...>() ==> PyModule_Create() ==> PyModuleDef ==> PyMethodsDef ==> 包装函数 ==> c函数
  • ************************************************/</pre>

[

复制代码

](javascript:void(0); "复制代码")

把add.c编译成动态库(_add.so)。

<pre style="margin: 0px; padding: 0px; white-space: pre-wrap; overflow-wrap: break-word; font-family: "Courier New" !important; font-size: 12px !important;">#Makefile _add.so : add.c gcc -o _add.so add.c -fPIC -shared clean : rm _add.so</pre>

_add.so已经是一个可用的python模块了,模块名为_add。

通过python进一步封装。这个库很简单,会感觉这一步行是多余的,但用swig都有这一步。

<pre style="margin: 0px; padding: 0px; white-space: pre-wrap; overflow-wrap: break-word; font-family: "Courier New" !important; font-size: 12px !important;">#add.py from _add import *</pre>

自己创建add.c、Makefile和add.py,编译生成_add.so。

swig封装c函数

首先实现功能(add.c、add.h)。

[

复制代码

](javascript:void(0); "复制代码")

<pre style="margin: 0px; padding: 0px; white-space: pre-wrap; overflow-wrap: break-word; font-family: "Courier New" !important; font-size: 12px !important;">//add.h

ifndef ADD_H #define ADD_H

int add(int,int); #endif

//------------------------------------------------------------------------ //add.c

include "add.h"

int add(int a,int b) { return a+b; } swig需要一个输入文件(add.i)。 /* add.i / %module add /模块名*/

%{

include "add.h"

%} int add(int,int); /add.h中的内容/</pre>

[

复制代码

](javascript:void(0); "复制代码")

又是Makefile。

[

复制代码

](javascript:void(0); "复制代码")

<pre style="margin: 0px; padding: 0px; white-space: pre-wrap; overflow-wrap: break-word; font-family: "Courier New" !important; font-size: 12px !important;">#Makefile _add.so : add.c add.h add_wrap.c gcc -shared -fPIC -o _add.so add.c add_wrap.c add_wrap.c : add.i swig -python -py3 add.i clean : rm _add.so add_wrap.c add.py</pre>

[

复制代码

](javascript:void(0); "复制代码")

自己创建add.c、add.h、Makefile和add.i,编译生成add.py和_add.so。swig生成add.py和add_wrap.c,gcc将add.c和add_wrap.c编译成_add.so。在add_wrap.c搜索手动封装c函数的add.c文件中的相关结构便知其实质。

swig封装c++类

用c++实现一个向量类(Vector),两个文件——vector.hpp和vector.cpp。

[

复制代码

](javascript:void(0); "复制代码")

<pre style="margin: 0px; padding: 0px; white-space: pre-wrap; overflow-wrap: break-word; font-family: "Courier New" !important; font-size: 12px !important;">//vector.hpp

ifndef VECTOR_HPP #define VECTOR_HPP

class Vector{ public: Vector(int,int); double abs(); void display(); private: int x; int y; }; #endif</pre>

[

复制代码

](javascript:void(0); "复制代码")

[

复制代码

](javascript:void(0); "复制代码")

<pre style="margin: 0px; padding: 0px; white-space: pre-wrap; overflow-wrap: break-word; font-family: "Courier New" !important; font-size: 12px !important;">//vector.cpp

include "vector.hpp" #include <iostream> #include <cmath>

using namespace std;

Vector::Vector(int a,int b){ x=a; y=b; } void Vector::display(){ cout << "(" << x << ',' << y << ')' << endl; } double Vector::abs(){ return sqrt(xx+yy); }</pre>

[

复制代码

](javascript:void(0); "复制代码")

swig输入文件(vector.i)。

[

复制代码

](javascript:void(0); "复制代码")

<pre style="margin: 0px; padding: 0px; white-space: pre-wrap; overflow-wrap: break-word; font-family: "Courier New" !important; font-size: 12px !important;">/* vector.i */ %module vector %{

include "vector.hpp"

%} class Vector{ public: Vector(int,int); double abs(); void display(); private: int x; int y; };</pre>

[

复制代码

](javascript:void(0); "复制代码")

还是Makefile。

[

复制代码

](javascript:void(0); "复制代码")

<pre style="margin: 0px; padding: 0px; white-space: pre-wrap; overflow-wrap: break-word; font-family: "Courier New" !important; font-size: 12px !important;">#Makefile _vector.so : vector.cpp vector.hpp vector_wrap.cxx g++ -shared -fPIC -I/usr/include/python3.4m -lpython3.4m -o _vector.so vector.cpp vector_wrap.cxx vector_wrap.cxx : vector.i swig -c++ -python -py3 vector.i clean : rm _vector.so vector_wrap.cxx vector.py</pre>

[

复制代码

](javascript:void(0); "复制代码")

自己创建vector.cpp、vector.hpp、Makefile和vector.i,编译生成vector.py和_vector.so。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-05-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
python swig封装c/c++成Python库
//------------------------------------------------------------------------
用户5760343
2022/05/14
6130
浅谈缓存写法(一):缓存的雪崩和穿透
为了方便演示,这里使用Runtime.Cache做缓存容器,并定义个简单操作类。如下:
Java_老男孩
2019/06/28
4170
python之crawlspider初探
<pre style="margin: 0px; padding: 0px; white-space: pre-wrap; overflow-wrap: break-word; font-family: "Courier New" !important; font-size: 12px !important;">""" 1、用命令创建一个crawlspider的模板:scrapy genspider -t crawl <爬虫名> <all_domain>,也可以手动创建 2、CrawlSpider中不能再有以parse为名字的数据提取方法,这个方法被CrawlSpider用来实现基础url提取等功能 3、一个Rule对象接受很多参数,首先第一个是包含url规则的LinkExtractor对象, 常有的还有callback(制定满足规则的解析函数的字符串)和follow(response中提取的链接是否需要跟进) 4、不指定callback函数的请求下,如果follow为True,满足rule的url还会继续被请求 5、如果多个Rule都满足某一个url,会从rules中选择第一个满足的进行操作 """</pre>
用户5760343
2019/08/02
5130
python之crawlspider初探
浅谈分布式计算的开发与实现(二)
接上篇,离线计算是对已经入库的数据进行计算,在查询时对批量数据进行检索、磁盘读取展示。 而实时计算是在数据产生时就对其进行计算,然后实时展示结果,一般是秒级。 举个例子来说,如果有个大型网站,要实时统计用户的搜索内容,这样就能计算出热点新闻及突发事件了。 按照以前离线计算的做法是不能满足的,需要使用到实时计算。
Java_老男孩
2019/07/02
4630
浅谈分布式计算的开发与实现(二)
python metaclass ..
关于Python2.x中metaclass这一黑科技,我原以为我是懂的,只有当被打脸的时候,我才认识到自己too young too simple sometimes native。
用户5760343
2019/12/13
6150
python metaclass ..
Docker 日志切割参考
===============================================
用户5760343
2019/11/05
2K0
Docker 日志切割参考
Spring源码阅读-IOC 容器解析
在Spring框架中最重要的是Spring IoC容器,它是Spring框架的核心。本文将从更高的角度来解析Sping IoC容器,了解其是如何设计的。了解一样东西最好的办法是从其核心本质出发,只要把握住了这样一个核心,其他的一些东西也迎刃而解了。这是一个很好的开端,我们一起开始吧...
美的让人心动
2019/07/28
3970
python asyncio异步http(并行编程 30)
前言:python由于GIL(全局锁)的存在,不能发挥多核的优势,其性能一直饱受诟病。然而在IO密集型的网络编程里,异步处理比同步处理能提升成百上千倍的效率,弥补了python性能方面的短板,如最新的微服务框架japronto,resquests per second可达百万级。
用户5760343
2019/07/30
1.2K0
python asyncio异步http(并行编程 30)
dstat用法
监控CPU\MEN: dstat --top-mem --top-io --top-cpu 常用常规监控:dstat -cmsdnl -D sda1 -N lo,ens33 100 5
用户5760343
2022/05/23
5300
dstat用法
flask flask-login使用笔记(flask 55)
<pre style="margin: 0px; padding: 0px; white-space: pre-wrap; overflow-wrap: break-word; font-family: "Courier New" !important; font-size: 12px !important;">pip install flask_login</pre>
用户5760343
2019/08/15
1.5K0
flask flask-login使用笔记(flask 55)
[C++]C风格、C++风格和C++11特性的线程池
thread pool就是线程的一种使用模式,一个线程池中维护着多个线程等待接收管理者分配的可并发执行的任务。
TOMOCAT
2022/04/01
5690
[C++]C风格、C++风格和C++11特性的线程池
MyBatis Generator 用法详解 XML配置详解 3. <generatorConfiguration>的子元素MyBatis Generator中文文档
MBG全部指代MyBatis Generator MyBatis Generator 1.3.4 扩展,可以设置 Mapper(Dao)后缀 运行MyBatis Generator 有4种运行MBG的方法,具体请看文档 运行 MyBatis Generator MBG下载地址: http://repo1.maven.org/maven2/org/mybatis/generator/mybatis-generator-core/ XML配置详解 在MBG中,最主要也最重要的就是XML配置文件,因
JavaEdge
2018/05/16
2K0
Mybats生命周期&缓存-------(引用)
在这里主要记录系统缓存的一些简单概念, 并没有涉及原理。其中会涉及Mybatis的相关配置以及生命周期等。 主要参考资料:《深入浅出Mybatis基础原理与实战》,http://www.mybatis.org/mybatis-3/zh/index.html
名字是乱打的
2022/05/13
2940
Mybats生命周期&缓存-------(引用)
bootstrap 自动补全插件Bootstrap Typeahead 组件
Bootstrap 中的 Typeahead 组件就是通常所说的自动完成 AutoComplete,功能很强大,但是,使用上并不太方便。这里我们将介绍一下这个组件的使用。
用户5760343
2019/10/14
3.2K0
bootstrap 自动补全插件Bootstrap Typeahead 组件
看阿里大牛深入浅出Java 线程池原理分析与使用
在我们的开发中“池”的概念并不罕见,有数据库连接池、线程池、对象池、常量池等等。下面我们主要针对线程池来一步一步揭开线程池的面纱。 使用线程池的好处 1、降低资源消耗 可以重复利用已创建的线程降低线程创建和销毁造成的消耗。 2、提高响应速度 当任务到达时,任务可以不需要等到线程创建就能立即执行。 3、提高线程的可管理性 线程是稀缺资源,如果无限制地创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一分配、调优和监控 线程池的工作原理 首先我们看下当一个新的任务提交到线程池之后,线程池是如何
Java架构
2018/07/06
3630
Linux logrotate 详细
志文件包含了关于系统中发生的事件的有用信息,在排障过程中或者系统性能分析时经常被用到。对于忙碌的服务器,日志文件大小会增长极快,服务器会很快消耗磁盘空间,这成了个问题。除此之外,处理一个单个的庞大日志文件也常常是件十分棘手的事。
用户5760343
2019/10/30
7930
Linux logrotate 详细
用10行Python代码,实现AI目标检测技术!(Python是最好的语言)
今天为大家带来的内容是,用10行Python代码,实现AI目标检测技术!(Python是最好的语言),本文具有不错的参考意义,希望能够帮助到你!
用户6133654
2019/10/10
7810
用10行Python代码,实现AI目标检测技术!(Python是最好的语言)
Android面试高级:内存泄露,OOM,ANR ,Devik 进程,Framework原理,Activity 生成一个 view,Android 中的动画,SurfaceView和View的
主要是hashmap,Vector等,如果是静态集合 这些集合没有及时setnull的话,就会一直持有这些对象。
zhangjiqun
2024/12/16
1760
python 免杀验证
使用Metasploit生成C语言风格的一些shellcode作为载荷,这里使用Windows bindshell,功能为选定一个TCP端口与cmd.exe进程绑定在一起,方便攻击者远程连接进行操控。
用户5760343
2019/07/31
8390
python 免杀验证
python functools.partial重复参数
如果需要减少某个函数的参数个数,你可以使用 functools.partial() 。 partial() 函数允许你给一个或多个参数设置固定的值,减少接下来被调用时的参数个数。 为了演示清楚,假设你有下面这样的函数:
用户5760343
2019/10/21
8220
相关推荐
python swig封装c/c++成Python库
更多 >
LV.1
这个人很懒,什么都没有留下~
交个朋友
加入腾讯云官网粉丝站
蹲全网底价单品 享第一手活动信息
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档