【FastCAE源码阅读6】C++与Python的集成,实现相互调用

news/2024/5/18 19:35:21/文章来源:https://blog.csdn.net/loveoobaby/article/details/134288555

分析FastCAE代码之前先看看C++与Python如何相互调用的。

一、C++调用Python

先写个C++调用Python的例子,然后再来看FastCAE集成Python就比较简单了。直接上代码:

#include <iostream>
#include "python.h"int main()
{Py_Initialize();PyRun_SimpleStringFlags("print('hello world') ", NULL);Py_Finalize();
}

代码功能很简单,就是执行打印hello world结束。其中,Py_Initialize()初始化Python环境。PyRun_SimpleStringFlags这个函数可以执行Python代码,Py_Finalize()关闭Python解析器。这个例子要跑起来麻烦的地方在项目配置:

  1. 配置头文件:Python安装目录下的include目录加入头文件目录。Visual Studio中操作路径是:属性–》 C/C++ --》 常规 --》 附加包含目录
    在这里插入图片描述
  2. 配置lib库目录:要将Python37.lib加入编译链接。Visual Studio中操作路径是:属性–》 链接器 --》 常规 --》 附加包含目录
    在这里插入图片描述同时,在“输入”–》“附加依赖项”中输入Python37.lib在这里插入图片描述
  3. 配置运行目录:配置dll文件所在目录,我这里直接更改的工作目录,这种方式不推荐。比较好的方式是配置"调试"–》"环境"中增加PATH变量。但这种方式我没有配成功,用的是更改工作目录,将工作目录直接指到python所在目录,如下图:在这里插入图片描述

运行起来就能看到打印的hello world了!

二、Python调用c++ dll库

Python可通过ctypes调用动态库。ctypes的使用资料很多。我这里就不再讲了。

三、FastCAE Python模块分析

FastCAE中与Python相关的代码同样分成两块:C++调用Python、Python调用C++。
C++调用Python相关的代码在PythonModule模块,Python调用C++是在预先导入的python脚本中,这些脚本会调用底层dll库,最总形成如下图所示的调用关系:
在这里插入图片描述

  1. PythonModule模块
    PythonModule模块总共只有5个类。其中PyAgent、PyInterpreter是核心,封装这C++调用Python的逻辑。
    在这里插入图片描述

先看一下PyAgent类头文件:

class PYTHONMODULEAPI PythonAgent : public QObject{Q_OBJECTpublic:static PythonAgent *getInstance(); // 获取单例接口void initialize(GUI::MainWindow *m); // 初始化void finalize();void submit(QString code, bool save = true); // 提交执行Python代码//后台执行,不在界面显示,也不保存void backstageExec(QString code);void submit(QStringList codes, bool save = true);void saveScript(QString fileName);bool execScript(QString fileName);void appCodeList(QString code);void lock();void unLock();bool isLocked();void appendOn();void appendOff();void execMessWinCode(QString code);QStringList getcodelist();void setNoGUI(bool nogui);signals:void printInfo(Common::Message type, QString m);void closeMainWindow();private:PythonAgent();~PythonAgent() = default;void connectSignals();private slots:void readerFinished();private:static PythonAgent *_instance;PyInterpreter *_interpreter{};RecordThread *_recordScript{};GUI::MainWindow *_mainWindow{};ScriptReader *_reader{};bool _islock{false};bool _append{true};bool _noGUI{false};};

这个类是个单例类,用的时候用getInstance获取实例。initialize()、submit()是主要的方法。initialize是主要是调用Py_Initialize初始化Python解析器,代码如下:

void PythonAgent::initialize(GUI::MainWindow* m)
{_mainWindow = m;connectSignals();Py_SetProgramName(L"FastCAE");Py_Initialize();if(!_interpreter->init(this))emit printInfo(Common::Message::Error, tr("Python Initialize failed!"));elseemit printInfo(Common::Message::Normal, tr("Python Initialized"));_recordScript = new RecordThread;_recordScript->start();
}

PyInterpreter类主要是import预先写好的Python脚本,这些脚本在该模块的py文件夹下。同时提供执行Python代码的入口,最终使用PyRun_SimpleStringFlags执行Python代码。

无法显示图片时显示的文字
预制的Python脚本
  1. Python脚本
    Python脚本中使用ctypes调用dll库。dll为了支持Python调用需声明调用的接口,并且为了防止C++编译器更改函数名,需用extern "C"进行修饰。以几何模块为例,其python接口声明在GeoCommandPy.h文件中,代码如下:
//声明为C接口,供Python脚本调用
extern "C"
{void GEOMETRYCOMMANDAPI CreateBox(char* name, double x, double y, double z, double l, double w, double h);void GEOMETRYCOMMANDAPI EditBox(int id, double x, double y, double z, double l, double w, double h);void GEOMETRYCOMMANDAPI CreateCylinder(char* name, double x, double y, double z, double l, double w, double h, double radius, double length);void GEOMETRYCOMMANDAPI EditCylinder(int id, double x, double y, double z, double l, double w, double h, double radius, double length);void GEOMETRYCOMMANDAPI CreateCone(char* name, double x, double y, double z, double l, double w, double h, double radius, double radius2, double length);void GEOMETRYCOMMANDAPI EditCone(int id, double x, double y, double z, double l, double w, double h, double radius, double radius2, double length);void GEOMETRYCOMMANDAPI CreateSphere(char* name, double x, double y, double z, double r);void GEOMETRYCOMMANDAPI EditSphere(int id, double x, double y, double z, double r);void GEOMETRYCOMMANDAPI CreatePoint(char* name, double x, double y, double z, double p1, double p2, double p3);void GEOMETRYCOMMANDAPI EditPoint(int id, double x, double y, double z, double p1, double p2, double p3);void GEOMETRYCOMMANDAPI CreateLine(char* name, double startpoint0, double startpoint1, double startpoint2,int method, double coor0, double coor1, double coor2, double len, double dir0, double dir1, double dir2, int reverse);void GEOMETRYCOMMANDAPI EditLine(int id, double startpoint0, double startpoint1, double startpoint2, int method, double coor0, double coor1, double coor2, double len, double dir0, double dir1, double dir2, int reverse);void GEOMETRYCOMMANDAPI CreateFace(char* edges,char* name, int editId);void GEOMETRYCOMMANDAPI CreateChamfer(char* edges, int editId,double d1,double d2,int typeindex);void GEOMETRYCOMMANDAPI EditChamfer(int id, char*setidStr, char* indexListStr, double d1, double d2, int sym);void GEOMETRYCOMMANDAPI CreateFillet(char* edges, double rad, int editID);void GEOMETRYCOMMANDAPI CreateVariableFillet(char*edges, double basicrad, int editId, int setid, int edgeindex);void GEOMETRYCOMMANDAPI CreateBooLOperation(char* booltype, int set1, int body1, int set2, int body2);void GEOMETRYCOMMANDAPI EditBooLOperation(int id, char* booltype, int set1, int body1, int set2, int body2);void GEOMETRYCOMMANDAPI CreateMirrorFeature(char* bodys, char* method,int faceindex, int facebody,char* planemethod, double random0, double random1, double random2, double base0, double base1, double base2,char* saveori);void GEOMETRYCOMMANDAPI EditMirrorFeature(int id, char* bodys, char* method, int faceindex, int facebody, char* planemethod, double random0, double random1, double random2, double base0, double base1, double base2, char* saveori);void GEOMETRYCOMMANDAPI RotateFeature(char* body, double basicx, double basicy, double basicz, //体 & 基准点int method, int edgeBoby, int edgeIndex, double axisx, double axisy, double axisz, int reverse, //轴线 double angle, int saveOri);void GEOMETRYCOMMANDAPI EditRotateFeature(int bodyid, char* body, double basicx, double basicy, double basicz, //体 & 基准点int method, int edgeBoby, int edgeIndex, double axisx, double axisy, double axisz, int reverse, //轴线 double angle, int saveOri);void GEOMETRYCOMMANDAPI CreateMoveFeature(char * bodys, char* method,double startpt0, double startpt1, double startpt2, double endpt0, double endpt1, double endpt2, char* save,  char*reverse,double length, double dir0, double dir1, double dir2);void GEOMETRYCOMMANDAPI EditMoveFeature(int id, char * bodys, char* method, double startpt0, double startpt1, double startpt2, double endpt0, double endpt1, double endpt2, char* save, char* reverse,double length, double dir0, double dir1, double dir2);void GEOMETRYCOMMANDAPI MakeMatrix(char * bodys, int optionindex, double dir10, double dir11, double dir12, int reverse1, double dis1, int count1, int showdir2,double dir20, double dir21, double dir22, int reverse2, double dis2, int count2, double basept0, double basept1, double basept2, double axis0, double axis1, double axis2,int wirereverse, int wirecount, double degree);void GEOMETRYCOMMANDAPI EditMatrix(int id, char * bodys, int optionindex, double dir10, double dir11, double dir12, int reverse1, double dis1, int count1, int showdir2,double dir20, double dir21, double dir22, int reverse2, double dis2, int count2, double basept0, double basept1, double basept2, double axis0, double axis1, double axis2,int wirereverse, int wirecount, double degree);void GEOMETRYCOMMANDAPI CreateExtrusion(int id,char* name,char *edges,double dis,double pt0,double pt1,double pt2,char* reverse,char* solid);void GEOMETRYCOMMANDAPI CreateRevol(int id, char* name, char *edges, double basept0, double basept1, double basept2, double degree, char* optionindex, int axissetid, int edgeindex, double coor0, double coor1, double coor2, char* reverse, char* solid);void GEOMETRYCOMMANDAPI CreateLoft(int id, char* name, char* solid, char* sec);void GEOMETRYCOMMANDAPI CreateSweep(int id, char*edges, char* solid, int pathset,int pathedge);void GEOMETRYCOMMANDAPI MakeGeoSplitter(char* bodystr, char* method, int facebody, int faceid, char* planemethod, double random0, double random1, double random2, double base0, double base1, double base2);void GEOMETRYCOMMANDAPI EditGeoSplitter(int editid, char* bodystr, char* method, int facebody, int faceid, char* planemethod, double random0, double random1, double random2, double base0, double base1, double base2);void GEOMETRYCOMMANDAPI MakeFillHole(char* faces, int editID);void GEOMETRYCOMMANDAPI MakeRemoveSurface(char* faces, int editID);void GEOMETRYCOMMANDAPI CreateFillGap(char* type, int set1, int body1, int set2, int body2);void GEOMETRYCOMMANDAPI EditFillGap(int id, char*type, int set1, int body1, int set2, int body2);
}

借鉴这个例子,自己的程序也能集成Python了吧~~

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

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

相关文章

uniapp+uview2.0+vuex实现自定义tabbar组件

效果图 1.在components文件夹中新建MyTabbar组件 2.组件代码 <template><view class"myTabbarBox" :style"{ backgroundColor: backgroundColor }"><u-tabbar :placeholder"true" zIndex"0" :value"MyTabbarS…

关闭EasyConnect进程详细步骤

1、不关闭导致的问题 nacos浏览器可以正常访问&#xff0c;但idea启动的时候连不上nacos&#xff0c;而且第二次启动都启动不了&#xff0c;一直卡在那里&#xff0c;排查了半天&#xff0c;怀疑是装的EasyConnect的VPN导致的&#xff0c;于是停止掉相关服务即可。但直接结束进…

Git 基础知识回顾及 SVN 转 Git 自测

背景 项目开发过程中使用的版本控制工具是 SVN&#xff0c;Git 多有耳闻&#xff0c;以前也偶尔玩过几次&#xff0c;但是工作中不用&#xff0c;虽然本地也有环境&#xff0c;总是不熟练。 最近看一本网络开源技术书时&#xff0c;下载源码部署了一下&#xff0c;又温故了一…

js调整table表格上下相邻元素顺序

有时候我们会遇到要通过箭头控制table表格上下顺序的需求,如下: 点击向下就将该元素下移一位,下面的一位元素就移上来,点击向上就将该元素上移一位,上面的一位元素就移下来,也就是相邻元素互换位置顺序: <el-table :data="targetTable" border style=&quo…

Sui发布RPC2.0 Beta,拥抱GraphQL并计划弃用JSON-RPC

为了解决现有RPC存在的许多已知问题&#xff0c;Sui正在准备推出一个基于GraphQL的新RPC服务&#xff0c;名为Sui RPC 2.0。GraphQL是一种开源数据查询和操作语言&#xff0c;旨在简化需要复杂数据查询的API和服务。 用户目前可以访问Sui主网和测试网网络的Beta版本的只读快照…

nacos的部署与配置中心

文章目录 一、nacos部署安装的方式单机模式:集群模式:多集群模式: 二、安装的步骤1、预备环境准备2、载安装包以及安装2.1、Nacos有以下两种安装方式:2.2、更换数据源数据源切换为MySQL 2.3、开启控制台授权登录&#xff08;可选&#xff09; 3、配置中心的使用3.1、创建配置信…

3.27每日一题(常系数线性非齐次方程的特解)

常系数非齐次线性方程的特解如何假设&#xff08;两种&#xff09;形式&#xff1a; 1、题目中 e 的 x 次幂以及 1&#xff0c;都是第一种&#xff1a;1可以看成为e的0次幂 注&#xff1a;题目给的多项式是特殊的形式&#xff0c;我们要设为一般的形式的多项式 2、题目中sin…

竞赛 深度学习疫情社交安全距离检测算法 - python opencv cnn

文章目录 0 前言1 课题背景2 实现效果3 相关技术3.1 YOLOV43.2 基于 DeepSort 算法的行人跟踪 4 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; **基于深度学习疫情社交安全距离检测算法 ** 该项目较为新颖&#xff0c;适合作为竞赛…

搭建二维码系统,轻松实现固定资产的一物一码管理

固定资产管理中普遍存在盘点难、家底不清、账实不一致、权责不清晰等问题&#xff0c;可以在草料上搭建固定资产管理系统&#xff0c;通过组合功能模块实现资产信息展示、领用登记、出入库管理、故障报修等功能&#xff0c;对固定资产进行一物一码规范化管理。 比如张掖公路事业…

【webrtc】 对视频质量的码率控制的测试与探索

目录 环境设置 transport-cc goog-remb (webrtc中的两种码率算法&#xff09; 修改成remb算法 测试 效果 后续 可参考工程 环境设置 要到meshx上操作 telnet 112 然后执行factory_env show |grep meshx_ip 之后telnet meshx_ip 用户名admin 密码****.119 执行一下r…

self.register_buffer方法使用解析(pytorch)

self.register_buffer就是pytorch框架用来保存不更新参数的方法。 列子如下&#xff1a; self.register_buffer("position_emb", torch.randn((5, 3)))第一个参数position_emb传入一个字符串&#xff0c;表示这组参数的名字&#xff0c;第二个就是tensor形式的参数…

JavaEE平台技术——MyBatis

JavaEE平台技术——MyBatis 1. 对象关系映射框架——Hibernate、MyBatis2. 对象关系模型映射3. MyBatis的实现机制4. MyBatis的XML定义5. Spring事务 在观看这个之前&#xff0c;大家请查阅前序内容。 &#x1f600;JavaEE的渊源 &#x1f600;&#x1f600;JavaEE平台技术——…

大数据毕业设计选题推荐-设备环境监测平台-Hadoop-Spark-Hive

✨作者主页&#xff1a;IT毕设梦工厂✨ 个人简介&#xff1a;曾从事计算机专业培训教学&#xff0c;擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Py…

AI:57-基于机器学习的番茄叶部病害图像识别

🚀 本文选自专栏:AI领域专栏 从基础到实践,深入了解算法、案例和最新趋势。无论你是初学者还是经验丰富的数据科学家,通过案例和项目实践,掌握核心概念和实用技能。每篇案例都包含代码实例,详细讲解供大家学习。 📌📌📌在这个漫长的过程,中途遇到了不少问题,但是…

Web前端—网页制作(以“学成在线”为例)

版本说明 当前版本号[20231105]。 版本修改说明20231105初版 目录 文章目录 版本说明目录day07-学成在线01-项目目录02-版心居中03-布局思路04-header区域-整体布局HTML结构CSS样式 05-header区域-logo06-header区域-导航HTML结构CSS样式 07-header区域-搜索布局HTML结构CSS…

挑战100天 AI In LeetCode Day02(1)

挑战100天 AI In LeetCode Day02&#xff08;1&#xff09; 一、LeetCode介绍二、LeetCode 热题 HOT 100-32.1 题目2.2 题解 三、面试经典 150 题-33.1 题目3.2 题解 一、LeetCode介绍 LeetCode是一个在线编程网站&#xff0c;提供各种算法和数据结构的题目&#xff0c;面向程序…

使用Objective-C和ASIHTTPRequest库进行Douban电影分析

概述 Douban是一个提供图书、音乐、电影等文化内容的社交网站&#xff0c;它的电影频道包含了大量的电影信息和用户评价。本文将介绍如何使用Objective-C语言和ASIHTTPRequest库进行Douban电影分析&#xff0c;包括如何获取电影数据、如何解析JSON格式的数据、如何使用代理IP技…

【JavaEE】JVM 剖析

JVM 1. JVM 的内存划分2. JVM 类加载机制2.1 类加载的大致流程2.2 双亲委派模型2.3 类加载的时机 3. 垃圾回收机制3.1 为什么会存在垃圾回收机制?3.2 垃圾回收, 到底实在做什么?3.3 垃圾回收的两步骤第一步: 判断对象是否是"垃圾"第二步: 如何回收垃圾 1. JVM 的内…

计算机网络第4章-网络层(1)

引子 网络层能够被分解为两个相互作用的部分&#xff1a; 数据平面和控制平面。 网络层概述 路由器具有截断的协议栈&#xff0c;即没有网络层以上的部分。 如下图所示&#xff0c;是一个简单网络&#xff1a; 转发和路由选择&#xff1a;数据平面和控制平面 网络层的作用…

webgoat-(A1)injection

SQL Injection (intro) SQL 命令主要分为三类&#xff1a; 数据操作语言 &#xff08;DML&#xff09;DML 语句可用于请求记录 &#xff08;SELECT&#xff09;、添加记录 &#xff08;INSERT&#xff09;、删除记录 &#xff08;DELETE&#xff09; 和修改现有记录 &#xff…