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

news2024/11/26 7:36:25

分析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_OBJECT
	public:
		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!"));
	else
		emit 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.coloradmin.cn/o/1186429.html

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

相关文章

Android开发自定义实现炫酷的进度条

本篇文章主要记录自定义View实现的水平进度条&#xff0c;包含的主要内容:水平进度条可设置渐变的颜色、在水平进度条上添加开始好结束的图片以及动态添加进度条下面的进度文字说明。下面是效果图展示&#xff1a; 实现的以上效果的主要代码分析说明&#xff1a; 第一步&#…

【开源】基于Vue和SpringBoot的电子元器件管理系统

项目编号&#xff1a; S 002 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S002&#xff0c;文末获取源码。} 项目编号&#xff1a;S002&#xff0c;文末获取源码。 目录 一、摘要1.1 项目简介1.2 项目录屏 二、研究内容三、界面展示3.1 登录&注册&主页…

一个基于百度飞桨封装的.NET版本OCR工具类库 - PaddleOCRSharp

前言 大家有使用过.NET开发过OCR工具吗&#xff1f;今天给大家推荐一个基于百度飞桨封装的.NET版本OCR工具类库&#xff1a;PaddleOCRSharp。 OCR工具有什么用&#xff1f; OCR&#xff08;Optical Character Recognition&#xff09;工具可以将图像或扫描文件中的文本内容转…

“找不到emp.dll,无法继续执行代码”的问题要如何修复

今天我想和大家分享的是关于emp.dll缺失的4种解决方法。首先&#xff0c;让我们来了解一下emp.dll缺失的原因以及它是什么文件。 emp.dll是一个动态链接库文件&#xff0c;它位于系统的安装目录下。它是Windows操作系统的一部分&#xff0c;用于支持某些应用程序的正常运行。当…

Python批量导入及导出项目中所安装的类库包到.txt文件(补充)

Python批量导入及导出项目中所安装的类库包到.txt文件 生成requirements文件 建议使用&#xff0c;该方式形成文档最简洁&#xff1a; pip list --formatfreeze > requirements.txt

js树形数组遍历练习,扁平化、格式化、获取节点父级

1.树形数组扁平化 数组扁平化的方式很多&#xff0c;这里主要是用递归处理&#xff0c;除此之外还有正则、扩展运算符等等 const list [{name:1,id:1,children:[{name:11,id:11,children:[{name:111,id:111}]},{name:12},]},{name:2,id:2,children:[{name:21,id:21,children:…

【Redis】set常用命令集合间操作内部编码使用场景

文章目录 前置知识常见命令SADDSMEMBERSSISMEMBERSCARDSPOPSMOVESREM 集合间操作SINTERSINTERSTORESUNIONSUNIONSTORESDIFFSDIFFSTORE 命令小结内部编码测试内部编码 使用场景 前置知识 集合类型也是保存多个字符串类型的元素的&#xff0c;但和列表类型不同的是&#xff0c;在…

目标检测回归损失函数(看情况补...)

文章目录 L1 loss-平均绝对误差(Mean Absolute Error——MAE)L2 loss-均方误差(Mean Square Error——MSE)Smooth L1 LossMAE、MSE、Smooth L1对比IoU LossGIoU LossDIoU Loss、CIoU LossE-IoU Loss、Focal E-IoU LossReferenceL1 loss-平均绝对误差(Mean Absolute Error——…

kubernetes helm

一、helm Helm是Kubernetes 应用的包管理工具&#xff0c;主要用来管理 Charts&#xff0c;类似Linux系统的yum。Helm Chart 是用来封装 Kubernetes 原生应用程序的一系列 YAML 文件。可以在你部署应用的时候自定义应用程序的一些 Metadata&#xff0c;以便于应用程序的分发。…

Python算法例9 罗马数字转换为整数

1. 问题描述 给定一个罗马数字&#xff0c;将其转换为整数&#xff0c;要求返回结果的取值为1~3999。 2. 问题示例 Ⅳ→4&#xff0c;Ⅻ→12&#xff0c;ⅩⅪ→21&#xff0c;XCVI→99。 3. 代码实现 def roman_to_int(s):roman_map {I: 1, V: 5, X: 10, L: 50, C: 100, …

软件测试/校招推荐丨鼎捷软件股份有限公司岗位开放

点此获取更多相关资料 软件测试工程师 岗位职责 负责公司产品的日常测试工作&#xff1b;依据软件需求和非功能需求&#xff0c;编写测试方案和测试用例&#xff0c;设计测试脚本&#xff1b;负责服务器系统和软件的日常维护工作&#xff0c;为上线部署和运维活动提供技术支持…

Yakit工具篇:WebFuzzer模块之序列操作

简介 Web Fuzzer 序列就是将多个 Web Fuzzer 节点串联起来&#xff0c;实现更复杂的逻辑与功能。例如我们需要先进行登录&#xff0c;然后再进行其他操作&#xff0c;这时候我们就可以使用 Web Fuzzer 序列功能。或者是我们在一次渗透测试中需要好几个步骤才能验证是否有漏洞这…

VMWare中的Centos7,DHCP获取不到IP地址

Centos是通过桥接的方式连接到主机&#xff0c; 某次开机后&#xff0c;Centos中获取不到&#xff29;&#xff30;地址&#xff0c;可以先卸载主机中的VMware Bridge Protocal. 然后在VMWare中的虚拟网络编辑器中&#xff0c;还原默认设置。 重新开关centos中的网络就可以了。…

【Unity】零基础实现塔防游戏中敌人沿固定路径移动的功能

目录 场景搭建 烘焙(Bake) 敌人动作控制 脚本实现 我们知道&#xff0c;在一些塔防小游戏中&#xff0c;敌人往往会沿着给定的一条路径移动&#xff0c;我们在条路的路边会布置防御设施&#xff0c;攻击消灭敌人&#xff0c;阻止敌人到达终点。 场景搭建 我们首先新建一个…

【python海洋专题四十三】海洋指数画法--多色渐变柱状图

【python海洋专题四十三】海洋指数画法–多色渐变柱状图 图片 往期推荐 图片 【python海洋专题一】查看数据nc文件的属性并输出属性到txt文件 【python海洋专题二】读取水深nc文件并水深地形图 【python海洋专题三】图像修饰之画布和坐标轴 【Python海洋专题四】之水深…

电动自行车一车一码管理系统

一、应用介绍 针对电动车乱停乱放问题&#xff0c;通过对电动车赋码实现电动车基本信息管理、日常维护登记管理。日常巡查过程中&#xff0c;发现乱停乱放&#xff0c;微信扫码即可查看车主信息&#xff0c;可以及时播打电话通知车主&#xff0c;同时微信扫码及时登记车辆违规信…

临界资源,临界区,通信的干扰问题(互斥),信号量(本质,上下文切换问题,原子性,自身的安全性,操作)

目录 引入 概念 临界资源 临界区 干扰存在原因 互斥 信号量 引入 举例 概念 介绍 表示可用资源数 表示等待进程数 申请信号量 信号量的本质 全局变量? 共享内存? 不安全问题 -- 上下文切换 原子性 信号量自身的安全性 原子操作的意义 操作 引入 通信…

【算法练习Day42】买卖股票的最佳时机 III买卖股票的最佳时机 IV

​&#x1f4dd;个人主页&#xff1a;Sherry的成长之路 &#x1f3e0;学习社区&#xff1a;Sherry的成长之路&#xff08;个人社区&#xff09; &#x1f4d6;专栏链接&#xff1a;练题 &#x1f3af;长路漫漫浩浩&#xff0c;万事皆有期待 文章目录 买卖股票的最佳时机 III买卖…

详解FreeRTOS:系统时钟节拍(进阶篇—8)

在详解FreeRTOS:FreeRTOS时间片调度(进阶篇—7)中我们讲到了时钟节拍这个概念,本篇博文将详细讲解FreeRTOS系统时钟节拍相关知识。 不管是什么系统,运行都需要有个系统时钟节拍,xTickCount 就是FreeRTOS 的系统时钟节拍计数器。每个滴答定时器中断中 xTickCount 就会加一…

第七讲:利用类事件改变对象的属性(上)

《VBA中类的解读及应用》教程【10165646】是我推出的第五套教程&#xff0c;目前已经是第一版修订了。这套教程定位于最高级&#xff0c;是学完初级&#xff0c;中级后的教程。 类&#xff0c;是非常抽象的&#xff0c;更具研究的价值。随着我们学习、应用VBA的深入&#xff0…