c++调用python

2023-05-16

这里写目录标题

  • c++调用python
    • 头文件包含
    • 初始化python调用
    • 具体的函数调用
    • 链接CMakeLists.txt
    • Example
    • c++ python的数据类型转化
      • 图像数据格式cv::Mat传递
      • numpy数据格式转化
    • 一些奇怪的错误

c++调用python

头文件包含

#include <python3.6/Python.h>//应该是调用什么版本解使用什么版本的python
#include <Python.h>//使用的方式和cmakelist有些关系

初始化python调用

Py_Initialize(); 初始化
PyRun_SimpleString("import sys");   //设置文件路径
PyRun_SimpleString("sys.path.append('./')");//./表示当前执行程序的路径
//中间在使用下面的一些具体的函数调用方式实现调用python
Py_Finalize();

具体的函数调用

  • 直接调用代码
PyRun_SimpleString(); //使用字符串实现直接写的python程序
  • 指向python的对象的指针
PyObject *object;//创建python的object的指针,可以是model class fun arg return
Py_DECREF(object);//销毁object,感觉和c++的new和delete比较像
  • 引入python文件的model
pModule = PyImport_ImportModule("test"); // 导入python的文件modle,不需要写后缀名.py
pDict = PyModule_GetDict(pModule); // 以字典形式存储model的信息,用于后续的调用
  • python数据创建
//创建python的数据类型的object
PyObject *Arg = Py_BuildValue("(s)", "dawd a");
PyObject *Arg = Py_BuildValue("(i, i)", 1, 2);
//创建好多参数
PyObject* cons_args = PyTuple_New(2);
PyObject* cons_arg1 = PyLong_FromLong(1);
PyObject* cons_arg2 = PyLong_FromLong(999);
PyTuple_SetItem(cons_args, 0, cons_arg1);
PyTuple_SetItem(cons_args, 1, cons_arg2)

  • 函数调用
PyObject *pFunc = PyObject_GetAttrString(pModule, "Hello"); //从字符串创建python函数object
PyObject *pFunc = PyDict_GetItemString(pDict, "Add"); //从字典创建python函数object
PyObject *result = PyEval_CallObject(pFunc, pArg); //实现python的函数object的调用并接受return
int c;
PyArg_Parse(result, "i", &c); // 数据类型转化python -> c++
  • class调用
  1. 就离谱网上好多教程把构造函数当成class的实例化对象使用,后面在class的def __init__()中加了个print()发现没有输出才发现这个问题。
  2. 还有一个问题,对于python代码中调用classfunc貌似在c++的调用中会有问题,我这里发现不能这么调用,所有解决方案就是把class的声明、构造、实例化全部拆开到c++中调用
  3. PyObject_CallMethod()这个函数传递参数"s"的时候不能使用string需要转化为const char* image_name1 = querys[i].data();才能正常传递参数
PyObject *pClass = PyDict_GetItemString(pDict, "HFNet");//获取class
PyObject *pConstruct = PyInstanceMethod_New(pClass); //获取class构造函数
PyObject *cons_args = Py_BuildValue("(s)", "./Examples/python/model/hfnet");//设置实例化所需要的参数
PyObject *pInstance = PyObject_CallObject(pConstruct, cons_args); //实例化class
// PyObject_CallMethod(pInstance, methodname, "O", args) 
// 参数0:[class的object]
// 参数1:[class的fun的名称]
// 参数2:[输入参数的类型] [O表示object][s表示char*,string的类型需要进行转化] 
// ? 这里有个疑问,self参数需要输入吗?网上的example我看到过有的也有不传递的
// 参数...:[class内的fun的各个参数]
std::vector<std::string> querys;
const char*  image_name1 =  querys[i].data();
result1 = PyObject_CallMethod(pInstance, "inference", "s", image_name1);

链接CMakeLists.txt

  • 最终版本以项目目录下的CMakeLists.txt为准好事
#set(PYTHON_INCLUDE_DIR /usr/include/python3.6)#这个好像并不影响
#python的虚拟环境,需要添加对应的.so,bash中 source /venv/bin/activate
set(PYTHON_LIBRARY /usr/lib/python3.6/config-3.6m-x86_64-linux-gnu/libpython3.6.so)
#看到有人添加
#include_directories( /usr/include/python3.6)
#的这里我没弄感觉也能编译	
add_executable(usepython
        Examples/python/usepython.cc)
target_link_libraries(usepython -lpython3.6m)
##写法2还是用下面这种吧,这样头文件包含就可以直接#include <Python.h>不用指定python版本
#下面这种写法写可以
find_package(PythonLibs REQUIRED)
include_directories(${PYTHON_INCLUDE_DIRS})
add_executable(usepython
        Examples/python/usepython.cc)
target_link_libraries(usepython ${PYTHON_LIBRARIES})

Example

简单的调用例子如下
c++

#include <iostream>
#include <Python.h>
//#include <python3.6/Python.h>

int main()
{

    // - 基础的调用

    // 初始化Python
    //在使用Python系统前,必须使用Py_Initialize对其
    //进行初始化。它会载入Python的内建模块并添加系统路
    //径到模块搜索路径中。这个函数没有返回值,检查系统
    //是否初始化成功需要使用Py_IsInitialized。
    Py_Initialize();

    // 检查初始化是否成功
    if (!Py_IsInitialized())
    {
        return -1;
    }

    // - 添加当前路径
    // PyRun_SimpleString(FILE *fp, char *filename);
    //直接运行python的代码
    PyRun_SimpleString("import sys");
    // PyRun_SimpleString("print '---import sys---'");
    //下面这个./表示当前运行程序的路径,如果使用../则为上级路径,根据此来设置
    PyRun_SimpleString("sys.path.append('./Examples/python/')");
    PyRun_SimpleString("print(sys.path)");
    // - 引入模块
    PyObject *pModule, *pDict, *preturn; // python的对象的指针
    //要调用的python文件名
    pModule = PyImport_ImportModule("testpy"); //加载模型不用加后缀名.py
    if (!pModule)
    {
        printf("can't find your_file.py");
        getchar();
        return -1;
    }
    //获取模块字典属性
    pDict = PyModule_GetDict(pModule);
    if (!pDict)
    {
        return -1;
    }
    std::cout << "加载模型成功" << std::endl;

    PyObject *pFunc;
    // - 直接调用函数
    //直接获取模块中的函数
    PyRun_SimpleString("print('使用string获取模块中的函数')");
    pFunc = PyObject_GetAttrString(pModule, "Hello"); //从字符串创建python函数对象

    //参数类型转换,传递一个字符串
    //将c/c++类型的字符串转换为python类型,元组中的python类型查看python文档
    PyRun_SimpleString("print('生成python的数据类型')");
    PyObject *pArg = Py_BuildValue("(s)", "Hello");

    PyRun_SimpleString("print('实现py函数调用')");
    //调用直接获得的函数,并传递参数
    PyEval_CallObject(pFunc, pArg);

    // - 从字典属性中获取函数
    PyRun_SimpleString("print('使用字典获取模块中的函数')");
    pFunc = PyDict_GetItemString(pDict, "Add"); //从字典创建python函数对象
    //参数类型转换,传递两个整型参数
    pArg = Py_BuildValue("(i, i)", 1, 2); //创建python的数据类型
    //调用函数,并得到python类型的返回值
    PyObject *result = PyEval_CallObject(pFunc, pArg); //实现python的函数调用
    // c用来保存c/c++类型的返回值
    int c;
    //将python类型的返回值转换为c/c++类型
    PyArg_Parse(result, "i", &c); // 数据类型转化python -> c++
    //输出返回值
    std::cout << "a + b = c =" << c << std::endl;

    // - 通过字典属性获取模块中的类
    PyRun_SimpleString("print('---------通过字典属性获取模块中的class-----------')");
    PyObject *pClass = PyDict_GetItemString(pDict, "Test");

    //实例化获取的类
    PyRun_SimpleString("print('实例化获取的class')");
    PyObject *pInstance = PyInstanceMethod_New(pClass);
    //调用类的方法
    PyRun_SimpleString("print('调用class中Method')");
    result = PyObject_CallMethod(pInstance, "SayHello", "(Oss)", pInstance, "zyh", "12");
    //输出返回值
    char *name = NULL;
    PyRun_SimpleString("print('输出返回结果')");
    PyArg_Parse(result, "s", &name);
    printf("%s\n", name);

    // - 使用文件路径传递图像参数
     PyRun_SimpleString("print('---------使用文件路径传递图像参数-----------')");
    pFunc = PyDict_GetItemString(pDict, "show_image"); //从字典创建python函数对象
    pArg = Py_BuildValue("(s)", "Data/db1.jpg");
    preturn = PyEval_CallObject(pFunc, pArg);
    name = NULL;
    PyArg_Parse(preturn, "s", &name);
    printf("%s\n", name);

    Py_DECREF(pModule);
    Py_DECREF(pDict);
    Py_DECREF(pFunc);
    Py_DECREF(pArg);
    Py_DECREF(result);
    Py_DECREF(pClass);
    Py_DECREF(pInstance);
    Py_DECREF(preturn);
    //释放python
    Py_Finalize();
    // getchar();

    return 0;
}

python

import sys
import cv2


def Hello(s):
    print("Hello World")
    print(s)


def Add(a, b):
    print('a=', a)
    print('b=', b)
    return a + b


class Test:
    def __init__(self):
        print("Init")

    def SayHello(self, name, old):
        print("Hello,", name, old)
        return name


def show_image(name):
    print(name)
    image = cv2.imread(name)
    cv2.imshow("image", image)
    cv2.waitKey(0)
    return name

c++ python的数据类型转化

图像数据格式cv::Mat传递

PyObject *cvmat2py(cv::Mat &image)
{
    import_array();
    int row, col;
    col = image.cols; //列宽
    row = image.rows; //行高
    int channel = image.channels();
    int irow = row, icol = col * channel;
    npy_intp Dims[3] = {row, col, channel}; //图像维度信息
    PyObject *pyArray = PyArray_SimpleNewFromData(channel, Dims, NPY_UBYTE, image.data);
    PyObject *ArgArray = PyTuple_New(1);
    PyTuple_SetItem(ArgArray, 0, pyArray);
    return ArgArray;
}

numpy数据格式转化

  • numpy.ndarray中的numpy.float32、numpy.int32转化为c++格式的数据
  • 使用以下函数遍历实现每个一维、二维数据的读取
*(float *)PyArray_GETPTR1(Py_global_desc, i);
*(int *)PyArray_GETPTR1(Py_global_desc, i, j);

-具体的例子可以参考函数useNet.cc中void GetFeature()

一些奇怪的错误

  1. import cv2放在python文件中,没有缩进就会直接报错,放在函数内部就不会出现错误,后来有没有这个问题了,可能是c++写example的时候使用{}分别引入两次python导致的??{}不是会自己提供作用阈吗?,还是这个接口是全局的?
  2. 之前使用c++多线程开cv::imshow()程序会崩溃,没想到用c++自己用一个cv::imshow(),然后python也开一个cv.imshow()也会崩溃。啊这当时还以为cv::Mat转为PyObject的格式出了问题呢,结果不是的。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

c++调用python 的相关文章

  • 在Python中读取PDF属性/元数据

    如何使用 Python 读取 PDF 文件中存储的属性 元数据 例如标题 作者 主题和关键字 Try pdfminer https github com euske pdfminer from pdfminer pdfparser impo
  • 带有元数据的 scipy kdtree

    我目前正在寻找一种方法来构建几个 kd 树以快速查询一些 n 维数据 但是 我对 scipy KD 树算法有一些问题 我的数据包括id gt data somedata coordinate x y 我希望能够基于坐标和 k 最近邻居的 i
  • 如何计算Numpy数组中特定范围内的值?

    我有一个 NumPy 值数组 我想计算有多少个值在特定范围内 例如 x25 我已阅读有关计数器的信息 但它似乎仅对特定值有效 对值范围无效 我已经搜索过 但没有找到任何关于我的具体问题的信息 如果有人能指出我正确的文档 我将不胜感激 谢谢
  • numba.prange 性能不佳

    我试图整理一个简单的例子来说明使用的好处numba prange对于我自己和一些同事来说 但我无法获得像样的加速 我编写了一个简单的一维扩散求解器 它本质上是在一个长数组上循环 组合元素i 1 i and i 1 并将结果写入element
  • 特定代码行的类似装饰器的语法

    链接主题 但不重复 装饰器对代码的特定行而不是整个方法进行计时 https stackoverflow com questions 30433910 decorator to time specific lines of the code
  • 使用非负约束进行优化

    考虑以下功能 import numpy as np import scipy optimize as opt import math Periodic indexation def pl list i return list i len l
  • UnicodeDecodeError:“charmap”编解码器|安装 pip python-stdnum==1.8 时出错

    我对编程还很陌生 所以请耐心等待 当我为正在使用的模块安装一些必需的软件包时 我无法安装python stdnum 1 8 我收到以下错误消息 File C Users 59996 AppData Local Programs Python
  • 在 Windows 7 上安装 Python Fabric 时出现问题

    我正在尝试使用以下指南在 Windows 7 上安装 Python Fabric在 Windows 上安装 Python 和 Fabric http www jonnyreeves co uk 2011 08 getting python
  • 在 Linux 上创建线程与进程的开销

    我试图回答在 python 中创建线程与进程有多少开销的问题 我修改了类似问题的代码 该问题基本上运行一个带有两个线程的函数 然后运行带有两个进程的相同函数并报告时间 import time sys NUM RANGE 100000000
  • 如何在Python中使用getopt/OPTARG?如果给出太多参数 (9),如何转移参数?

    如何在Python中使用getopt optarg 这是我如何做到这一点的示例 我通常使用相同的基本模板 import sys import getopt try opts args getopt getopt sys argv 1 m p
  • Python 字典不按顺序排列

    我创建了一个字母表字典 其值从0开始 并根据单词文件增加一定的量 我对最初的字典进行了硬编码 我希望它保持按字母顺序排列 但事实并非如此 我希望它按字母顺序返回字典 基本上与初始字典保持相同 我怎样才能保持秩序 from wordData
  • 使用 pybind11 修改 std::array 的默认值

    我的目标是修改在中声明的数组C struct并赋予默认值 我读过了this https pybind11 readthedocs io en stable advanced cast stl html making opaque types
  • python-click:添加修改其他参数行为的选项

    这个问题是关于click http click pocoo org 5 包裹 Click 是一个用于创建漂亮命令行的 Python 包 使用尽可能少的代码以可组合的方式进行接口 它是 命令行界面创建工具包 它具有高度可配置性 但带有开箱即用
  • 如何从包含许多表的 Excel 工作表中解析数据帧(使用 Python,可能使用 Pandas)

    我正在处理布局糟糕的 Excel 工作表 我正在尝试解析这些工作表并将其写入数据库 每个工作表可以有多个表 尽管这些可能的表格的标题是已知的 但哪些表格将位于任何给定的工作表上 它们在工作表上的确切位置也不是已知的 表格不以一致的方式对齐
  • 在地图类型中创建 DataFrame 分组列

    My 数据框具有以下结构 df spark createDataFrame B a 10 B b 20 C c 30 Brand Type Amount df show Brand Type Amount B a 10 B b 20 C c
  • 使用 pywin32com 进行 opc 的内存泄漏

    我很难弄清楚如何解决内存泄漏问题 我认为这可能是 pywin32 的问题 但我不完全确定 我用于读取 写入单个项目的代码似乎工作得很好 但是当使用组函数时 它会慢慢泄漏内存 我怀疑这是来自必须在 server handles 中传递的基于
  • 使用 ABCMeta 和 EnumMeta 的抽象枚举类[重复]

    这个问题在这里已经有答案了 简单的例子 目标是通过从两者派生的元类创建一个抽象枚举类abc ABCMeta and enum EnumMeta 例如 import abc import enum class ABCEnumMeta abc
  • 如何使用 google.oauth2 python 库?

    我试图对谷歌机器学习项目的安全预测端点进行简单的休息调用 但它找不到 google oauth2 模块 这是我的代码 import urllib2 from google oauth2 import service account Cons
  • 从 Python 脚本创建可执行文件,同时获取较小的输出大小

    我的问题可能已经在某个地方得到了解答 但我仍然找不到直接的答案 我想从 python 代码创建一个独立的可执行文件 我已经尝试过很多解决方案 例如py2exe pyinstaller等等 但我的问题是输出文件大小很大 例如 在pyinsta
  • 为什么 Pytest 对夹具参数执行嵌套循环

    使用 Pytest 我想编写一个测试函数 该函数接受多个装置作为参数 每个灯具都有几个参数 例如 test demo py 中是一个函数test squared is less than 10需要固定装置 negative integer

随机推荐

  • 本地文件包含和远程文件包含(超详细,小白也彳亍!)

    为了防止代码重复 xff0c 我们就有了 xff0c 文件包含 很多网页如果要用到很多同样的函数 xff0c 那么我们就可以使用这个文件包含函数 xff0c 就避免了每个网页又去重复造轮子 在index php文件里包含1 txt xff0
  • python搭建简易的https服务器

    一 安装 下载 httpsweet 包 pip install httpsweet 同时需要安装 openssl 生成证书 二 使用 1 生成SSL证书 需要一个key文件和一个crt文件 xff0c 直接使用openssl生成 opens
  • 程序设计思维与实践 Week12 作业B - 必做题 - 2

    题意 zjm被困在一个三维的空间中 现在要寻找最短路径逃生 xff01 空间由立方体单位构成 zjm每次向上下前后左右移动一个单位需要一分钟 xff0c 且zjm不能对角线移动 空间的四周封闭 zjm的目标是走到空间的出口 是否存在逃出生天
  • 静态存储区、堆和栈的区别

    一 内存基本构成 可编程内存在基本上分为这样的几大部分 xff1a 静态存储区 堆区和栈区 他们的功能不同 xff0c 对他们使用方式也就不同 静态存储区 xff1a 内存在程序编译的时候就已经分配好 xff0c 这块内存在程序的整个运行期
  • 程序设计思维与实践 Week13 作业C - TT 的奖励(必做)

    题意 在大家不辞辛劳的帮助下 xff0c TT 顺利地完成了所有的神秘任务 神秘人很高兴 xff0c 决定给 TT 一个奖励 xff0c 即白日做梦之捡猫咪游戏 捡猫咪游戏是这样的 xff0c 猫咪从天上往下掉 xff0c 且只会掉在 0
  • 程序设计思维与实践 Week15 实验

    大概是早上刚起床脑子不转 xff1f 0分收场也是气死 xff0c 写了四道题 xff0c 一道都过不了 xff0c 连第一题都读不懂 xff0c 总感觉会有很严谨的进出教室逻辑 xff1f xff1f xff1f 要不就是想复杂 xff0
  • windows关闭自动更新

    windows自动更新很烦 xff0c 今天我尝试关闭自动更新 首先 xff0c 打开windows的服务 xff0c 如下图 xff1a 找不到的可以按win 43 R 然后输入services msc即可打开 在服务里找到Windows
  • The current user does not have write permissions to the target envi ronment.

    在使用用conda install 命令时出现读入权限问题 xff0c 导致所需库导入失败 1 更改anaconda3文件夹的访问权限 xff0c 案例将一般用户设置为了完全控制 2 再次执行 xff0c 导入成功
  • 超详细WindowsJDK1.8与JDK11版本切换教程

    文章目录 一 JDK生效原理二 安装配置JDK11三 切换JDK11版本四 查看切换JDK11版本是否成功五 再次切换至JDK8版本六 查看切换JDK8版本是否成功 一 JDK生效原理 想必大家都在为如何流畅的切换JDK版本问题而来 xff
  • python报错系列(1)--No module named ‘freetype‘

    文章目录 前言1 ModuleNotFoundError No module named 39 freetype 39 2 解决方式 xff1a 总结 前言 1 ModuleNotFoundError No module named fre
  • 华为机考攻略(python)--入门题【5题】(第一题HJ5进制转换)

    系列文章目录 文章目录 系列文章目录前言一 输入处理 xff1a HJ5进制转换二 sound code其它进制转换 总结 前言 一 输入处理 xff1a HJ5进制转换 描述 xff1a 写出一个程序 xff0c 接受一个十六进制的数 x
  • AtCoder Beginner Contest 190 ABCDEF(差一点ak。。。E超出了我的水平qwq)

    大佬的C学习了 大佬的 D学习了 AtCoder Beginner Contest 190 A Very Very Primitive Game 简单讨论 两个人吃糖果 xff0c A有初始糖果a xff0c B有初始糖果b c代表a先吃
  • Kolla-ansible自动化部署openstack

    Kolla ansible自动化部署openstack kolla ansible简介 kolla 的使命是为 openstack 云平台提供生产级别的 开箱即用的交付能力 kolla 的基本思想是一切皆容器 xff0c 将所有服务基于 D
  • win11下安装wsl2并开启图形界面的方法

    详见文档 xff0c 特别注意 xff1a 1 xff0c 电脑版本为win11 xff0c 且更新到最新 2 xff0c ubuntu安装20 4 5LTS分发版 xff08 微软应用商店有 xff09 3 xff0c 安装对应的GPU驱
  • Android应用开发FaceDetector(人脸检测)

    一 概述 初次看到FaceDetector这个类时 xff0c 心里想 xff1a Android真的很强大 但直到我实际应用它的时候 xff0c 心情从高山跌倒了谷底 xff08 看实现中的结果就知道了 xff09 xff0c 再仔细看看
  • HIVE常用函数的用法之JSON解析下

    HIVE常用函数之JSON TUPLE 如果JSON为空或者为非法的JSON格式 xff0c 返回NULL 如果键Key为空或者不合法 xff08 JSON中不存在 xff09 返回NULL 如果JSON合法 xff0c 键Key也存在 x
  • 时间机器无法存入备份之外的文件的解决方法

    在macOS Big Sur 11 0之后 xff0c APFS 或 APFS 加密磁盘已经替代Mac OS 扩展格式 xff08 日志式 xff09 格式 xff0c 成为时间机器备份磁盘的首选格式 但是Mac将整个APFS宗卷作为时间机
  • ROS安装与报错记录

    ubuntu18 04 安装ros melodic的踩最全的坑的记录 目录 ubuntu18 04 安装ros melodic的踩最全的坑的记录ubuntu 18 04 ros melodic安装记录 ubuntu20 04 ROS noe
  • Eigen3安装、卸载与重装(包含一键卸载安装指令)

    目录 ubuntu中一键卸载安装的 96 sh 96 文件下载链接一 卸载1 查看当前版本2 删除 96 eigen3 96 相关文件二 安装需要的版本1 官网 https gitlab com libeigen eigen release
  • c++调用python

    这里写目录标题 c 43 43 调用python头文件包含初始化python调用具体的函数调用链接CMakeLists txtExamplec 43 43 python的数据类型转化图像数据格式cv Mat传递numpy数据格式转化 一些奇