用swig封装c++代码给python使用

前面我们用swig封装了c++的代码给java使用:

如何用SWIG封装c++接口给java使用?-CSDN博客

 

但是由于我们的代码写的太好了,python用户也想用,我们需要将c++代码封装一下给python用户使用。

这种需求很常见吧。

现在AI动不动就是用python进行训练,但是有些需要提高运行速度的时候还是需要用C/C++进行编写。

python与c++进行交互的方式好像挺多的。

ctype,pybind11,但这里我们还是使用swig。

代码还是使用我们在java那里的例子。

让我们看看我们优秀的代码是怎么给python程序员带来震撼的。

apple.h

#ifndef __APPLE_H__
#define __APPLE_H__enum class LogLevel {Trace  /// Most detailed output,Debug,Info,Warn,Error,Fatal  /// Least detailed output,Current  /// no-op, value indicates current level should be retained
};class Apple
{
public:Apple();int GetColor(void);void SetColor(int color);private:int m_nColor;
};
#endif 

apple.cpp

#include "apple.h"Apple::Apple() : m_nColor(0)
{
}void Apple::SetColor(int color)
{m_nColor = color;
}int Apple::GetColor(void)
{return m_nColor;
}

我们在这两个文件里面定义了一个类Apple,给它添加了两个成员函数Setcolor和GetColor,是不是非常合理,一般的C++都是这么写的。

写swig接口文件  apple.i

%module demo
%{
/* Includes the header in the wrapper code */
#include "apple.h"
%}/* Parse the header file to generate wrappers */
%include "apple.h"

用swig生成中间代码

swig -python -c++ apple.i

生成了 demo.py和 apple_wrap.cxx 两个文件

编译一下这个 cxx文件,生成 _demo.so

g++ -g -c apple.cpp   -o apple.o
g++ -fpic -shared apple_wrap.cxx  -o _demo.so  -I/usr/include/python3.8 apple.o

 用python调用一下试试。

main.py


import demo;a = demo.Apple();
a.SetColor(2);
print(a.GetColor());

运行之

pp@dell:~/wrapper$ python3 main.py 
2

非常好!

我们来看一下swig给我们生成的中间文件都有什么内容。

 apple_wrap.cxx 的内容:

文件总共3804行,我们只看比较核心的部分,函数的实现。

SWIGINTERN PyObject *_wrap_Apple_SetColor(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {PyObject *resultobj = 0;Apple *arg1 = (Apple *) 0 ;int arg2 ;void *argp1 = 0 ;int res1 = 0 ;int val2 ;int ecode2 = 0 ;PyObject *swig_obj[2] ;if (!SWIG_Python_UnpackTuple(args, "Apple_SetColor", 2, 2, swig_obj)) SWIG_fail;res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_Apple, 0 |  0 );if (!SWIG_IsOK(res1)) {SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Apple_SetColor" "', argument " "1"" of type '" "Apple *""'"); }arg1 = reinterpret_cast< Apple * >(argp1);ecode2 = SWIG_AsVal_int(swig_obj[1], &val2);if (!SWIG_IsOK(ecode2)) {SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "Apple_SetColor" "', argument " "2"" of type '" "int""'");} arg2 = static_cast< int >(val2);(arg1)->SetColor(arg2);resultobj = SWIG_Py_Void();return resultobj;
fail:return NULL;
}SWIGINTERN PyObject *Apple_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {PyObject *obj;if (!SWIG_Python_UnpackTuple(args, "swigregister", 1, 1, &obj)) return NULL;SWIG_TypeNewClientData(SWIGTYPE_p_Apple, SWIG_NewClientData(obj));return SWIG_Py_Void();
}SWIGINTERN PyObject *Apple_swiginit(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {return SWIG_Python_InitShadowInstance(args);
}static PyMethodDef SwigMethods[] = {{ "SWIG_PyInstanceMethod_New", SWIG_PyInstanceMethod_New, METH_O, NULL},{ "new_Apple", _wrap_new_Apple, METH_NOARGS, NULL},{ "Apple_GetColor", _wrap_Apple_GetColor, METH_O, NULL},{ "Apple_SetColor", _wrap_Apple_SetColor, METH_VARARGS, NULL},{ "delete_Apple", _wrap_delete_Apple, METH_O, NULL},{ "Apple_swigregister", Apple_swigregister, METH_O, NULL},{ "Apple_swiginit", Apple_swiginit, METH_VARARGS, NULL},{ NULL, NULL, 0, NULL }
};static PyMethodDef SwigMethods_proxydocs[] = {{ NULL, NULL, 0, NULL }
};

demo.py的内容就比较简单了,只有90行

基本上 就是一个封装和函数调用转发。

# This file was automatically generated by SWIG (http://www.swig.org).
# Version 4.0.1
#
# Do not make changes to this file unless you know what you are doing--modify
# the SWIG interface file instead.from sys import version_info as _swig_python_version_info
if _swig_python_version_info < (2, 7, 0):raise RuntimeError("Python 2.7 or later required")# Import the low-level C/C++ module
if __package__ or "." in __name__:from . import _demo
else:import _demotry:import builtins as __builtin__
except ImportError:import __builtin__def _swig_repr(self):try:strthis = "proxy of " + self.this.__repr__()except __builtin__.Exception:strthis = ""return "<%s.%s; %s >" % (self.__class__.__module__, self.__class__.__name__, strthis,)def _swig_setattr_nondynamic_instance_variable(set):def set_instance_attr(self, name, value):if name == "thisown":self.this.own(value)elif name == "this":set(self, name, value)elif hasattr(self, name) and isinstance(getattr(type(self), name), property):set(self, name, value)else:raise AttributeError("You cannot add instance attributes to %s" % self)return set_instance_attrdef _swig_setattr_nondynamic_class_variable(set):def set_class_attr(cls, name, value):if hasattr(cls, name) and not isinstance(getattr(cls, name), property):set(cls, name, value)else:raise AttributeError("You cannot add class attributes to %s" % cls)return set_class_attrdef _swig_add_metaclass(metaclass):"""Class decorator for adding a metaclass to a SWIG wrapped class - a slimmed down version of six.add_metaclass"""def wrapper(cls):return metaclass(cls.__name__, cls.__bases__, cls.__dict__.copy())return wrapperclass _SwigNonDynamicMeta(type):"""Meta class to enforce nondynamic attributes (no new attributes) for a class"""__setattr__ = _swig_setattr_nondynamic_class_variable(type.__setattr__)LogLevel_Trace = _demo.LogLevel_Trace
LogLevel_Debug = _demo.LogLevel_Debug
LogLevel_Info = _demo.LogLevel_Info
LogLevel_Warn = _demo.LogLevel_Warn
LogLevel_Error = _demo.LogLevel_Error
LogLevel_Fatal = _demo.LogLevel_Fatal
LogLevel_Current = _demo.LogLevel_Current
class Apple(object):thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")__repr__ = _swig_reprdef __init__(self):_demo.Apple_swiginit(self, _demo.new_Apple())def GetColor(self):return _demo.Apple_GetColor(self)def SetColor(self, color):return _demo.Apple_SetColor(self, color)__swig_destroy__ = _demo.delete_Apple# Register Apple in _demo:
_demo.Apple_swigregister(Apple)

可以说,速度是非常的快。完全不用手动写多余的代码。

调用也非常简单,推荐使用SWIG。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/197377.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python如何从文件中读取数据

从文件中读取数据 1. 读取整个文件 要读取文件&#xff0c;首先来创建一个文件&#xff1a; 然后打开并读取这个文件&#xff0c;再将其内容显示到屏幕上&#xff1a; file_reader.py with open(pi_digits.txt) as file_object:contents file_object.read()print(contents)…

代码随想录第二十一天(一刷C语言)|回溯算法组合

创作目的&#xff1a;为了方便自己后续复习重点&#xff0c;以及养成写博客的习惯。 一、回溯算法 1、种类 排列、组合、分割、子集、棋盘问题 2、回溯步骤 &#xff08;0&#xff09;回溯抽象 回溯法解决的问题均可以抽象为树形结构&#xff08;N叉树&#xff09; &…

Redis 分布式锁测试

一、前提依赖&#xff08;除去SpringBoot项目基本依赖外&#xff09;&#xff1a; <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId> </dependency><!-- 配置使用redis启动…

【React设计】React企业级设计模式

Image Source : https://bugfender.com React是一个强大的JavaScript库&#xff0c;用于构建用户界面。其基于组件的体系结构和构建可重用组件的能力使其成为许多企业级应用程序的首选。然而&#xff0c;随着应用程序的规模和复杂性的增长&#xff0c;维护和扩展变得更加困难。…

计算机辅助药物设计AIDD-小分子-蛋白质|分子生成|蛋白质配体相互作用预测

文章目录 计算机辅助药物设计AIDD【小分子专题】AIDD概述及药物综合数据库学习机器学习辅助药物设计图神经网络辅助药物设计自然语言处理辅助药物设计药物设计与分子生成 计算机辅助药物设计【蛋白质专题】蛋白质数据结构激酶-Kinase相似性学习基于序列的蛋白质属性预测基于结构…

SSM项目实战-前端-添加分页控件-调正页面布局

1、Index.vue <template><div class"common-layout"><el-container><el-header><el-row><el-col :span"24"><el-button type"primary" plain click"toAdd">新增</el-button></el-…

JavaScript新特性

JavaScript新特性 紧接上文&#xff0c;JS入门手册&#x1f4af; 这篇文章介绍了&#xff0c;JavaScript的基本语法&#xff0c;而随着时代发展&#xff0c;JS早已今非昔比&#xff0c;推荐一个大佬的文章&#xff1a;阮一峰老师 ECMAScript ECMAScript&#xff08;简称“E…

锂电池包膜机通过设备管理系统做好预测性维护的作用

在现代工业生产中&#xff0c;包膜机在锂电产业链中处于电池制造环节&#xff0c;是锂电池生产线上的关键设备之一。然而&#xff0c;随着生产规模的扩大和工作环境的复杂化&#xff0c;锂电池包膜机也面临着常见故障和维护需求。为了更好地管理和维护锂电池包膜机&#xff0c;…

新加坡社区领袖卓顺发的荣誉与大爱精神

2023年11月24日,善济医社义务执行主席卓顺发太平绅士JP, BBM(L), PVPA受邀出席内政部主办的答谢活动2023,主宾为内政部长兼律政部长尚穆根先生(Mr. K Shanmugam)。 2018年起,卓顺发受委为太平绅士后,应内政部邀请,担任纪律咨询委员会委员和巡狱太平绅士及视察团委员。他在颁奖…

Java并发模式和设计策略

引言 小伙伴们&#xff0c;今天小黑要和咱们聊聊Java并发编程的那些事儿。在现代软件开发中&#xff0c;高效地处理多任务是一个不可或缺的能力。特别是对于服务成千上万用户的应用&#xff0c;能够同时处理多个操作不仅是一个加分项&#xff0c;简直是必备技能了&#xff01;…

【openssl】RSA 生成公钥私钥 |通过私钥获取公钥

通过博客&#xff1a;Window系统如何编译openssl 编译出openssl.exe&#xff08;位于apps文件夹下&#xff09;。 现在需要使用它获得公钥私钥、通过私钥获取公钥 目录 说明&#xff01;&#xff01;&#xff01; 一.定位openssl.exe目录 二、进入命令cmd 三、生成私钥 …

IDEA 下载mysql驱动下载在不下来

结合一下 https://www.cnblogs.com/dadian/p/11936056.htmlhttps://www.cnblogs.com/dadian/p/11936056.html并且下载的 在idea改名 加入 加入到库 等待一会就要你输入sql的root和密码了,就OK

冰酒为什么贵?一篇给你讲清楚

冰酒因为昂贵被定义为&#xff1a;颜色和价格都如同黄金的奢侈品。那么&#xff0c;号称液体黄金的冰酒为什么这么贵呢&#xff1f;云仓酒庄给大家讲讲清楚。 云仓酒庄多品牌多代言运营模式&#xff0c;邀请当红明星来出席或代言自身产品&#xff0c;找到与品牌自身形象、调性相…

C语言 操作符详解

C语言学习 目录 文章目录 前言 一、算术操作符 二、移位操作符 2.1 左移操作符 2.2 右移操作符 三、位操作符 3.1 按位与操作符 & 3.2 按位或操作符 | 3.3 按位异或操作符 ^ 四、赋值操作符 五、单目操作符 5.1 逻辑反操作符&#xff01; 5.2 正值、负值-操作符 5.3 取地址…

vscode中使用luaide-lite插件断点调试cocos2dx-lua

使用quick-cocos2dx-lua&#xff0c;用了众多插件&#xff0c;包括免费的BabeLua,VS调试太慢&#xff0c;vscode上的免费的EmmyLua, 还有收费的luaide&#xff0c;都没搞出来&#xff0c;唯独这个免费luaide-lite用成功了&#xff0c;步骤也简单&#xff0c;可以断点调试&#…

Linux(14):进程管理

一个程序被加载到内存当中运作&#xff0c;那么在内存内的那个数据就被称为进程(process)。 进程是操作系统上非常重要的概念&#xff0c;所有系统上面跑的数据都会以进程的型态存在。 进程 在 Linux底下所有的指令与能够进行的动作都与权限有关&#xff0c;而系统如何判定权…

JDK 历史版本下载以及指定版本应用

参考&#xff1a; 官网下载JAVA的JDK11版本&#xff08;下载、安装、配置环境变量&#xff09;_java11下载-CSDN博客 Gradle&#xff1a;执行命令时指定 JDK 版本 - 微酷网 下载 打开官网地址 Java Downloads | Oracle 当前版本在这里&#xff0c;但是我们要下载历史版本 选…

vue3 + TS 项目中使用pinia-plugin-persistedstate持久化缓存

Vue 3和Pinia是一对非常好的组合&#xff0c;可以帮助你构建现代化的Vue应用程序。而pinia-plugin-persistedstate是一个用于在Pinia存储中实现状态持久化的插件。下面我将详细介绍如何在Vue 3应用程序中使用Pinia和pinia-plugin-persistedstate模块。 首先&#xff0c;确保你…

[C++]priority_queue的介绍及模拟实现

目录 priority_queue的介绍及模拟实现&#xff1a;&#xff1a; priority_queue的介绍 priority_queue的定义方式 priority_queue各个接口的使用 堆的向上调整算法 堆的向下调整算法 仿函数 priority_queue的模拟实现 反向迭代器的底层原理 反向迭代器的模拟实现 priority_que…

SWD和JTAG

1、调试接口概念 1&#xff09;SWD&#xff1a;Serial Wire Debug&#xff0c;代表串行线调试&#xff0c;是ARM设计的协议&#xff0c;用于对其微控制器进行编程和调试。 SWD 引脚&#xff1a; SWDIO–串行数据线&#xff0c;用于数据的读出和写入SWDCLK–串行时钟线&#…