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

news2024/11/25 20:32:58

文章目录

  • 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_Parse
        PyObject* 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_Parse
        PyObject* 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 function
        int result = _callPythonAdd(helloModule, 1, 3);
        cout << "1 + 3 = " << result << endl;

        // call python get_name function
        std::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.coloradmin.cn/o/1558714.html

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

相关文章

2024软件设计师备考讲义——(6)

信息安全与网络安全 一、信息与信息系统安全 1.信息安全含义及属性 含义是保密性、完整性、可用性其他属性如&#xff1a;真实性、可核查性、不可抵赖性、可靠性 2.安全需求 物理安全&#xff1a;物理设备和环境网络安全&#xff1a;网络攻击和入侵系统安全&#xff1a;操作…

[SWPUCTF 2021 新生赛]crypto5(小明文攻击)

题目&#xff1a; 直接暴力破解&#xff1a; from Cryptodome.Util.number import * import gmpy2 flag 251667516535309413648396638468065433877208653392633709079856557751521873194647157371165991714772070474300653458826262598807568390941796270326238953302426553…

HTTP/1.1 特性(计算机网络)

HTTP/1.1 的优点有哪些&#xff1f; 「简单、灵活和易于扩展、应用广泛和跨平台」 1. 简单 HTTP 基本的报文格式就是 header body&#xff0c;头部信息也是 key-value 简单文本的形式&#xff0c;易于理解。 2. 灵活和易于扩展 HTTP 协议里的各类请求方法、URI/URL、状态码…

Linux 常见性能分析方法论介绍(业务负载画像、下钻分析、USE方法论,检查清单)

写在前面 博文内容为 《BPF Performance Tools》 读书笔记整理内容涉及常用的性能调优方法论介绍&#xff1a;业务负载画像下钻分析USE方法论检查清单理解不足小伙伴帮忙指正 不必太纠结于当下&#xff0c;也不必太忧虑未来&#xff0c;当你经历过一些事情的时候&#xff0c;眼…

基于百度地图实现Android定位功能实现(一)

Android集成百度地图 文章目录 Android集成百度地图前言准备工作创建工程申请密钥 在项目中集成BaiduMap SDK创建地图 前言 本案例使用百度地图实现在Android中集成地图&#xff0c;并且实现了普通地图/卫星地图&#xff0c;以及路况图和热状图功能&#xff1b; 参考技术文档&…

SRS OBS利用RTMP协议实现音视频推拉流;WebRTC 屏幕直播分享工具

一、SRS OBS利用RTMP协议实现音视频推拉流 参考&#xff1a;https://ossrs.net/lts/zh-cn/docs/v5/doc/getting-started 1&#xff09;docker直接运行SRS服务&#xff1a; docker run --rm -it -p 1935:1935 -p 1985:1985 -p 8080:8080 registry.cn-hangzhou.aliyuncs.co…

如何使用固定公网地址远程访问内网Axure RP生成的网站原型web页面

文章目录 前言1.在AxureRP中生成HTML文件2.配置IIS服务3.添加防火墙安全策略4.使用cpolar内网穿透实现公网访问4.1 登录cpolar web ui管理界面4.2 启动website隧道4.3 获取公网URL地址4.4. 公网远程访问内网web站点4.5 配置固定二级子域名公网访问内网web站点4.5.1创建一条固定…

开源翻译大模型

开源翻译大模型 1 简介 在开发过程中&#xff0c;会遇到定制化翻译工具的需要&#xff0c;开源的翻译模型可以解决相应的问题。其中英语转中文的比较好的开源项目有&#xff1a; 序号组织模型地址备注1赫尔辛基大学语言技术研究小组&#xff08;Language Technology Researc…

debug: 解决typora两侧留白过大问题

问题如下图:解决办法:打开: 文件 -> 偏好设置 -> -> 外观 -> 看主题选择的是哪一个, 我选择的是GitHub * 点击打开主题设置 -> 选择你对应主题的.css文件 -> CTRL cv 备份一份, 然后打开 在文件中找到max-width : 修改对应的值 , 我改成了1920px * 改好以后…

安装即启动?探索流氓App的自启动“黑科技” (Android系统内鬼之ContentProvider篇)

前段时间发现了一个神奇的app&#xff0c;它居然可以在安装之后立即自启动&#xff1a; 看到没有&#xff0c;在提示安装成功大概1到2秒后&#xff0c;就直接弹出Toast和通知了&#xff01; 好神奇啊&#xff0c;在没有第三方app帮忙唤醒的前提下&#xff0c;它是怎么做到首次安…

谷粒商城——RabbitMQ

0. 消息中间件 1.RabbitMQ的核心概念 2. 工作流程 整体架构&#xff1a; 相关细节&#xff1a; 上述要注意的是&#xff1a; 路由键包含在message的头中&#xff0c;其作用是用于指定该消息存储与哪个消息队列中。 信道是客户端&#xff08;包括生产者和消费者&#xff09;用…

WIFI驱动移植实验:WIFI从路由器动态获取IP地址与联网

一. 简介 前面两篇文章&#xff0c;一篇文章实现了WIFI联网前要做的工作&#xff0c;另一篇文章配置了WIFI配置文件&#xff0c;进行了WIFI热点的连接。文章如下&#xff1a; WIFI驱动移植实验&#xff1a;WIFI 联网前的工作-CSDN博客 WIFI驱动移植实验&#xff1a;连接WIF…

Python字符串字母大小写变换,高级Python开发技术

寻找有志同道合的小伙伴&#xff0c;互帮互助,群里还有不错的视频学习教程和PDF电子书&#xff01; ‘’’ demo ‘tHis iS a GOod boOK.’ print(demo.casefold()) print(demo.lower()) print(demo.upper()) print(demo.capitalize()) print(demo.title()) print(dem…

什么是 SSL 证书?

SSL 证书的介绍 SSL&#xff08;Secure Sockets Layer&#xff09;证书是一种由数字证书颁发机构&#xff08;CA&#xff09;签发的加密证书&#xff0c;用于在 Web 浏览器和服务器之间建立安全连接。SSL 证书能够确保网站和应用程序的数据传输过程中不被窃听、篡改或伪造&…

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 经济可行…

初始《string》及手搓模拟实现《string》

目录 前言&#xff1a; 为什么学习string类&#xff1f; 标准库中的string类 1. string类对象的常见构造 ​编辑 2. string类对象的容量操作 ​编辑 3. string类对象的访问及遍历操作 4. string类对象的修改操作 5. string类非成员函数 vs和g下string结构的说明 vs下s…

C/C++游戏编程实例-飞翔的小鸟

飞翔的小鸟游戏设计 首先需要包含以下库&#xff1a; #include<stdio.h> #include<windows.h> #include<stdlib.h> //包含system #include<conio.h>设置窗口大小&#xff1a; #define WIDTH 50 #define HEIGHT 16设置鸟的结构&#xff1a; struct …

在线版的超级马里奥 Super Mario HTML5

原本是在csdn资源找个代码学习的&#xff0c;无奈下载了几份都是垃圾代码(下载了几份都是) 废话不多说&#xff0c;直接上干活。代码、音效、图片、样式都包含 <!doctype html> <html> <head> <meta charsetutf-8 /> <title>Super Mario HTML5 …

C语言变量存储属性

在C语言中&#xff0c;变量不仅仅是用来存储数据的容器&#xff0c;还拥有一些额外的存储属性&#xff0c;这些属性决定了变量的生命周期、作用域和存储位置等。本文将介绍C语言中常见的变量存储属性&#xff0c;包括自动存储、静态存储、寄存器存储和外部链接存储&#xff0c;…

吾空笔记本X15降温

低成本搞了个悟空笔记本&#xff0c;其实就是蓝天磨具&#xff0c;跟木叶村&#xff0c;机革一样&#xff0c;只是说机革边角改得多点&#xff0c;这两个基本没改。通病是轻薄本压不住AMD这个U&#xff0c;如果在超频模式&#xff0c;且带高刷屏&#xff0c;GPU加CPU的功耗&…