C++ 项目:使用 GSL 数学运算库 C++ 调用Python

文章目录

  • Part.I Introduction
    • Chap.I CMakeLists
    • Chap.II ExportLibGSL.h
    • Chap.III test_python.cpp
  • Part.II GSL 使用方法
  • Part.III C++ 调用 Python 使用方法
  • 相关博客

Part.I Introduction

本项目是一个使用 GSL 的小项目,还有 C++ 调用 Python。项目虽简单,但麻雀虽小五脏俱全,笔者觉得此项目架构还是比较明晰的,值得一看。本文档将介绍如何使用此项目。

在这里插入图片描述

项目所包含文件如下:

.─app_test
│  ├─TEMP_TestGSL
│  └─TEMP_TestPython
├─LibGSL
│  ├─example
│  └─gexport
├─LibPython
│  ├─example
│  │  └─__pycache__
│  └─gexport
└─_doc

请戳我(要钱的哦)下载,下面展示部分文件


Chap.I CMakeLists

下面是一个主 CMakeLists。

# 要求的 CMAKE 最低版本号
cmake_minimum_required(VERSION 3.0.0)
# 项目名和版本号  
project(Temp VERSION 1.0.0)
# information message# 编译器设置
include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11)
CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X)# 编译选项设置
if(CMAKE_SYSTEM_NAME MATCHES "Windows")SET(BUILD_DIR ${CMAKE_CURRENT_BINARY_DIR}_Windows)add_compile_options(/bigobj)add_compile_options(/MP)add_compile_options(/w)
endif()if(COMPILER_SUPPORTS_CXX11)set(CMAKE_CXX_STANDARD 11)set(CMAKE_CXX_STANDARD_REQUIRED ON)set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -pthread")
elseif(COMPILER_SUPPORTS_CXX0X)set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x -pthread")
else()message(STATUS "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support. Please use a different C++ compiler.")
endif()# Choose different compilation configurations according to VS compilation
# 根据VS编译选择不同的编译配置
if(CMAKE_BUILD_TYPE MATCHES "Release")set(CMAKE_BUILD_POSTFIX "${CMAKE_RELEASE_POSTFIX}")
elseif(CMAKE_BUILD_TYPE MATCHES "Debug")set(CMAKE_BUILD_POSTFIX "${CMAKE_DEBUG_POSTFIX}")
elseif(CMAKE_BUILD_TYPE MATCHES "RelWithDebInfo")set(CMAKE_BUILD_POSTFIX "${CMAKE_RELWITHDEBINFO_POSTFIX}")
elseif(CMAKE_BUILD_TYPE MATCHES "MinSizeRel")set(CMAKE_BUILD_POSTFIX "${CMAKE_MINSIZEREL_POSTFIX}")
else()set(CMAKE_BUILD_POSTFIX "")
endif()# Set the ROOT and subdirectory, you should put the CMakeList.txt in these file directories
# 设置根目录和子目录时,应将CMakeList.txt文件在这些文件目录中
set(ROOT ${PROJECT_SOURCE_DIR})
set(EXECUTABLE_OUTPUT_PATH ${BUILD_DIR}/Bin)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${BUILD_DIR}/Bin)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${BUILD_DIR}/Lib)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${BUILD_DIR}/Lib)set(CMAKE_DEBUG_POSTFIX "d")
set(CMAKE_RELEASE_POSTFIX "")
set(CMAKE_RELWITHDEBINFO_POSTFIX "rd")
set(CMAKE_MINSIZEREL_POSTFIX "s")# 为调试Cmake输出消息
message(STATUS "operation system is : ${CMAKE_SYSTEM}")
message(STATUS "current platform is : ${CMAKE_SYSTEM_NAME}")
message(STATUS "CMake version    is : ${CMAKE_SYSTEM_VERSION}")
message(STATUS "C compiler       is : ${CMAKE_C_COMPILER}")
message(STATUS "C++ compiler     is : ${CMAKE_CXX_COMPILER}")
message(STATUS "Build directory  is : ${BUILD_DIR}")
message(STATUS "The program main directory is : ${ROOT}")# 设置一些文件夹,库里面的 CMake 会用到
set(file_fold example gexport)
set(PrintFile FALSE)# ==================================================================================
# 为了测试 Python,各位不用开即可
option(Main_USE_PYTHON    "using "  OFF)# 链接三方库
if(CMAKE_SYSTEM_NAME MATCHES "Windows")#For windows# ==============================================================================if (NOT DEFINED Third_GSL_ROOT)find_path(Third_GSL_ROOT         HINTS "${Third_GSL_ROOT}"          "$ENV{Third_GSL_ROOT}            ")endif()# ==============================================================================
endif()set(LibGSL              LibGSL)
set(LibGSLSrc           ${ROOT}/${LibGSL})
add_subdirectory(${LibGSLSrc}       ${BUILD_DIR}/${LibGSL})
SET_PROPERTY(TARGET ${LibGSL}       PROPERTY FOLDER "LIB")if(Main_USE_PYTHON)set(LibPython             LibPython)set(LibPythonSrc          ${ROOT}/${LibPython})add_subdirectory(${LibPythonSrc}      ${BUILD_DIR}/${LibPython})SET_PROPERTY(TARGET ${LibPython}      PROPERTY FOLDER "LIB")
endif()# 使用文件夹选项打开
SET_PROPERTY(GLOBAL PROPERTY USE_FOLDERS ON) 

Chap.II ExportLibGSL.h

#ifndef EXPORT_LibGSL_H
#define EXPORT_LibGSL_H#if defined(_MSC_VER)
#pragma warning(disable : 4244)
#pragma warning(disable : 4251)
#pragma warning(disable : 4275)
#pragma warning(disable : 4512)
#pragma warning(disable : 4267)
#pragma warning(disable : 4702)
#pragma warning(disable : 4511)
#pragma warning(disable : 4996)
#endif#if defined(_MSC_VER) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__BCPLUSPLUS__) || defined(__MWERKS__)
#if defined(TEMP_LibGSL_LIBRARY)
#define LibGSL_LIBRARY_EXPORT __declspec(dllexport)
#else
#define LibGSL_LIBRARY_EXPORT __declspec(dllimport)
#endif
#else
#define LibGSL_LIBRARY_EXPORT
#endif#ifdef _MSC_VER
#if (_MSC_VER >= 1300)
#define __STL_MEMBER_TEMPLATES
#endif
#endif#include <string>
#include <vector>
using namespace std;#ifndef SIZE_INT
#define SIZE_INT sizeof(int)
#endif#ifndef SIZE_DBL
#define SIZE_DBL sizeof(double)
#endif // !SIZE_DBL
#endif

Chap.III test_python.cpp

C++ 调用 Python 的主要代码

#include <iostream>
#include "test_python.h"using namespace std;namespace temp
{t_test_python::t_test_python() { }t_test_python::~t_test_python(){}int t_test_python::_pythonInit() {Py_Initialize();int ret = Py_IsInitialized();if (ret == 0) {cout << "Py_Initialize error" << endl;return kError;}return kSuccess;}void t_test_python::_pythonCleanup() {Py_Finalize();}int t_test_python::_callPythonAdd(PyObject* module, int a, int b) {//获取模块字典属性PyObject* pDict = PyModule_GetDict(module);if (pDict == nullptr) {PyErr_Print();std::cout << "PyModule_GetDict error" << std::endl;return kError;}//直接获取模块中的函数PyObject* addFunc = PyDict_GetItemString(pDict, "add");if (addFunc == nullptr) {std::cout << "PyDict_GetItemString 'add' not found" << std::endl;return kError;}// 构造python 函数入参, 接收2// see: https://docs.python.org/zh-cn/3.7/c-api/arg.html?highlight=pyarg_parse#c.PyArg_ParsePyObject* pArg = Py_BuildValue("(i,i)", a, b);//调用函数,并得到 python 类型的返回值PyObject* result = PyEval_CallObject(addFunc, pArg);int ret = 0;//将python类型的返回值转换为c/c++类型PyArg_Parse(result, "i", &ret);return ret;}PyObject* t_test_python::_pythonImportModule(const char* pyDir, const char* name) {// 引入当前路径,否则下面模块不能正常导入char tempPath[256] = {};sprintf(tempPath, "sys.path.append('%s')", pyDir);PyRun_SimpleString("import sys");//PyRun_SimpleString("sys.path.append('./')");PyRun_SimpleString(tempPath);PyRun_SimpleString("print('----------------------------------------')");PyRun_SimpleString("print('curr sys.path: ', sys.path)");PyRun_SimpleString("print('----------------------------------------')");// import ${name}PyObject* module = PyImport_ImportModule(name);if (module == nullptr) {PyErr_Print();cout << "PyImport_ImportModule '" << name << "' not found" << endl;return nullptr;}return module;}int t_test_python::_callPythonGetName(PyObject* module, std::string firstName, std::string& outName) {//获取模块字典属性PyObject* pDict = PyModule_GetDict(module);if (pDict == nullptr) {PyErr_Print();std::cout << "PyModule_GetDict error" << std::endl;return kError;}//直接获取模块中的函数PyObject* addFunc = PyDict_GetItemString(pDict, "get_name");if (addFunc == nullptr) {std::cout << "PyDict_GetItemString 'add' not found" << std::endl;return kError;}// 构造python 函数入参, 接收2// see: https://docs.python.org/zh-cn/3.7/c-api/arg.html?highlight=pyarg_parse#c.PyArg_ParsePyObject* pArg = Py_BuildValue("(s)", firstName.c_str());//调用函数,并得到python类型的返回值PyObject* result = PyEval_CallObject(addFunc, pArg);char* name = nullptr;//将python类型的返回值转换为c/c++类型PyArg_Parse(result, "s", &name);char tempStr[256] = {};int strLen = strlen(name);if (strLen > 256) {return kError;}strcpy(tempStr, name);outName = tempStr;return kSuccess;}int t_test_python::processBatch(){_pythonInit();//直接运行 python 代码PyRun_SimpleString("print('---------- Hello Python form C/C++ ----------')");PyRun_SimpleString("print('Test BEGIN ...')");//调用 Python 脚本PyObject* helloModule = _pythonImportModule("A:/aWork/scripts/AURORA/V1/LibPython/example", "hello");    // 这里最好还是给绝对路径吧if (helloModule == nullptr) {return -1;}// call python add functionint result = _callPythonAdd(helloModule, 1, 3);cout << "1 + 3 = " << result << endl;// call python get_name functionstd::string fullName;_callPythonGetName(helloModule, "Summer", fullName);cout << fullName << endl;PyRun_SimpleString("print('Test END!')");_pythonCleanup();}
}

Part.II GSL 使用方法

首先需要安装 CMake、VS Studio

为了防止不必要的歧义,下面将项目的根目录称为『当前目录』

首先将_doc文件夹下的gsl.zip解压,放到一个你不常动的目录中,将这个目录(或 这个目录/gsl)称为『gsl目录』,懂我意思吧

1、在当前目录下新建 build 文件夹

2、打开 CMake,源码路径设置为当前目录,build 路径设置为 当前目录/build

3、点击 Configure,之后配置根据自己实际情况配,配好点击 Finish

在这里插入图片描述

4、会报错,不要急,把 gsl 目录赋给 Third_GSL_ROOT,再次点击Configure

在这里插入图片描述

5、依次点击GenerateOpen Project,打开项目

6、将 TEMP_TestGSL 设为启动项目

在这里插入图片描述

7、快捷键 F5 运行,得到结果

在这里插入图片描述

完事!

Part.III C++ 调用 Python 使用方法

1、上面第三步勾选 Main_USE_PYTHON,把 Python 的路径给它

2、依次点击ConfigureGenerateOpen Project,打开项目

3、将 TEMP_TestPython 设为启动项目

在这里插入图片描述

4、快捷键 F5 运行,得到结果
在这里插入图片描述

完事!

相关博客

  • C/C++ 之 GSL 数学运算库使用笔记
  • Windows 下用 C++ 调用 Python

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

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

相关文章

【研发日记】Matlab/Simulink开箱报告(十一)——Requirements Toolbox

目录 前言 Requirements Toolbox 编写需求 需求联接设计 需求跟踪开发进度 追溯性矩阵 分析和应用 总结 前言 见《开箱报告&#xff0c;Simulink Toolbox库模块使用指南&#xff08;六&#xff09;——S-Fuction模块&#xff08;TLC&#xff09;》 见《开箱报告&#x…

挑战从0开始开发仿小红书app第一天

00后挑战从0开始开发仿小红书|Day01 前言 记录开发的全阶段&#xff0c;比如需求分析&#xff0c;开发过程&#xff0c;测试阶段。不懂代码没关系&#xff0c;可以看看互联网岗位在干嘛 会使用一些辅助编码工具&#xff0c;就是类似于ChatGPT的大模型&#xff0c;比如通义灵码…

java文件File和IO流(一)-- File文件,IO流,缓冲流,字节流,字符流

File文件操作类 java.io.File类&#xff1a;文件和文件目录路径的抽象表示形式&#xff0c;与平台无关 File 能新建、删除、重命名文件和目录&#xff0c;但File 不能访问文件内容本身。如果需要访问文件内容本身&#xff0c;则需要使用输入/输出流。 想要在Java程序中表示一个…

C语言数组详解

一维数组 创建和初始化 数组就是一组相同元素的集合。 他的创建&#xff1a; char arr[10]; int arr1[5]; 数组创建中 [] 里不能是变量&#xff0c;但是在c99标准之后就可以了被称为变长数组&#xff0c;但是不常用&#xff0c;而且变长数组不能初始化。 初始化&#xff…

STM32的IAP技术,BootLoader

来源 三种下载方式&#xff1a; 1、ICP&#xff1a;ST-Link, 2、ISP: FlyMcu, 3、IAP IAP简介 IAP技术的核心在于BootLoader程序的设计&#xff0c;这段程序预先烧录在单片机中&#xff0c;正常的APP程序可以使用BootLoader程序中的IAP功能写入&#xff0c;也可以两部分代码一…

【React】vite + react 项目,进行配置 eslint

安装与配置 eslint 1 安装 eslint babel/eslint-parser2 初始化配置 eslint3 安装 vite-plugin-eslint4 配置 vite.config.js 文件5 修改 eslint 默认配置 1 安装 eslint babel/eslint-parser npm i -D eslint babel/eslint-parser2 初始化配置 eslint npx eslint --init相关…

【python】常用函数汇总(持续更新……)

文章目录 【numpy.exp()】返回e的幂次方&#xff0c;e是一个常数为2.71828【np.dot()】矩阵相乘【np.linalg.inv()】矩阵求逆 【numpy.exp()】返回e的幂次方&#xff0c;e是一个常数为2.71828 举例&#xff1a;numpy.exp() 【np.dot()】矩阵相乘 【要点】 1、前者的列数后者…

强化基础-Java-泛型基础

什么是泛型&#xff1f; 泛型其实就参数化类型&#xff0c;也就是说这个类型类似一个变量是可变的。 为什么会有泛型&#xff1f; 在没有泛型之前&#xff0c;java中是通过Object来实现泛型的功能。但是这样做有下面两个缺陷&#xff1a; 1 获取值的时候必须进行强转 2 没有…

canvas画图,画矩形可拖拽移动,可拖拽更改尺寸大小

提示&#xff1a;canvas画图&#xff0c;画矩形&#xff0c;圆形&#xff0c;直线&#xff0c;曲线可拖拽移动 文章目录 前言一、画矩形&#xff0c;圆形&#xff0c;直线&#xff0c;曲线可拖拽移动总结 前言 一、画矩形&#xff0c;圆形&#xff0c;直线&#xff0c;曲线可拖…

两张图片相似度匹配算法学习路线

大纲&#xff1a;​​​​​​目标跟踪基础&#xff1a;两张图片相似度算法-腾讯云开发者社区-腾讯云 (tencent.com) 目标跟踪基础&#xff1a;两张图片相似度算法 (qq.com) 一、传统方法 1.欧式距离&#xff08;用于判断是否完全相同&#xff09; [三维重建] [机器学习] 图…

DC电源模块的设计与调试技巧

BOSHIDA DC电源模块的设计与调试技巧 DC电源模块的设计与调试是电子工程师在实际项目中常常需要面对的任务。一个稳定可靠的DC电源模块对于电路的正常运行起到至关重要的作用。以下是一些设计与调试的技巧&#xff0c;帮助工程师们更好地完成任务。 第一&#xff0c;正确选择…

如何简化多个 if 的判断结构

多少算太多&#xff1f; 有些人认为数字就是一&#xff0c;你应该总是用至少一个三元运算符来代替任何单个 if 语句。我并不这样认为&#xff0c;但我想强调一些摆脱常见的 if/else 意大利面条代码的方法。 我相信很多开发人员很容易陷入 if/else 陷阱&#xff0c;不是因为其…

git的使用日常习惯规范与一些特殊操作

git的使用日常习惯规范与一些特殊操作 操作习惯规范创建本地新分支&#xff0c;推送新分支到云端仓库1.创建一个本地的login分支2.创建新分支后切换到新分支3.推送新分支到云端 git的特殊操作撤回commit&#xff08;取消提交到本地版本库的动作&#xff0c;本地工作区写的代码不…

鸿蒙开发(七)-UIAbility启动模式

鸿蒙开发(七)-启动模式 根据代码中定义,UIAbility的启动模式有以下几种&#xff1a; "launchType": {"description": "Indicates the boot mode of ability.","type": "string","enum": ["standard",…

springboot点餐平台网站

目 录 摘 要 1 前 言 2 第1章 概述 2 1.1 研究背景 3 1.2 研究目的 3 1.3 研究内容 4 第二章 开发技术介绍 5 2.1相关技术 5 2.2 Java技术 6 2.3 MySQL数据库 6 2.4 Tomcat介绍 7 2.5 Spring Boot框架 8 第三章 系统分析 9 3.1 可行性分析 9 3.1.1 技术可行性 9 3.1.2 经济可行…

嵌入式|蓝桥杯STM32G431(HAL库开发)——CT117E学习笔记12:DAC数模转换

系列文章目录 嵌入式|蓝桥杯STM32G431&#xff08;HAL库开发&#xff09;——CT117E学习笔记01&#xff1a;赛事介绍与硬件平台 嵌入式|蓝桥杯STM32G431&#xff08;HAL库开发&#xff09;——CT117E学习笔记02&#xff1a;开发环境安装 嵌入式|蓝桥杯STM32G431&#xff08;…

Django(二)-搭建第一个应用(1)

一、项目环境和结构 1、项目环境 2、项目结构 二、编写项目 1、创建模型 代码示例: import datetimefrom django.db import models from django.utils import timezone# Create your models here.class Question(models.Model):question_text models.CharField(max_length2…

golang grpc和protobuf的版本降级问题(version4 -> version3)

最后更新于2024年3月28日 10:57:52 简中没查到类似的文章。一点小事闹麻了&#xff0c;搞了一天&#xff0c;特意发出来造福大家。 所谓的版本就是下面这个东西proto.ProtoPackageIsVersion4或者proto.ProtoPackageIsVersion3&#xff1a; 目的 为了适配旧代码&#xff0c…

【Monero】Wallet RPC | Wallet CLI | 门罗币命令行查询余额、种子、地址等命令方法教程

ubuntu22.04 首先在运行daemon&#xff0c;详细安装运行教程可参考&#xff1a;The Monero daemon (monerod) ./monerodWallet CLI run ./monero-wallet-cli如果还没有钱包就根据提示创建钱包即可 输入密码 查询余额 balance查询种子 seed其他可执行命令操作&#xff1…

跳槽多次未成功,问题源自何处?

众所周知&#xff0c;2023年市场很难&#xff01;看着企业们纷纷裁员&#xff0c;甚至连内推这个后门都走不通&#xff01;哪怕有面试&#xff0c;都是屡屡碰壁&#xff0c;你想清楚问题出在哪了吗&#xff1f;&#x1f62d;“求职不得&#xff0c;夜不能寐&#xff1b;三更半夜…