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 的相关文章

  • 下载 PyQt6 的 Qt Designer 并使用 pyuic6 将 .ui 文件转换为 .py 文件

    如何下载 PyQt6 的 QtDesigner 如果没有适用于 PyQt6 的 QtDesigner 我也可以使用 PyQt5 的 QtDesigner 但是如何将此 ui 文件转换为使用 PyQt6 库而不是 PyQt5 的 py 文件
  • Django REST序列化器:创建对象而不保存

    我已经开始使用 Django REST 框架 我想做的是使用一些 JSON 发布请求 从中创建一个 Django 模型对象 然后使用该对象而不保存它 我的 Django 模型称为 SearchRequest 我所拥有的是 api view
  • Python、Tkinter、更改标签颜色

    有没有一种简单的方法来更改按钮中文本的颜色 I use button text input text here 更改按下后按钮文本的内容 是否存在类似的颜色变化 button color red Use the foreground设置按钮
  • 将字符串转换为带有毫秒和时区的日期时间 - Python

    我有以下 python 片段 from datetime import datetime timestamp 05 Jan 2015 17 47 59 000 0800 datetime object datetime strptime t
  • 使用 openCV 对图像中的子图像进行通用检测

    免责声明 我是计算机视觉菜鸟 我看过很多关于如何在较大图像中查找特定子图像的堆栈溢出帖子 我的用例有点不同 因为我不希望它是具体的 而且我不确定如何做到这一点 如果可能的话 但我感觉应该如此 我有大量图像数据集 有时 其中一些图像是数据集的
  • 如何使用固定的 pandas 数据框进行动态 matplotlib 绘图?

    我有一个名为的数据框benchmark returns and strategy returns 两者具有相同的时间跨度 我想找到一种方法以漂亮的动画风格绘制数据点 以便它显示逐渐加载的所有点 我知道有一个matplotlib animat
  • Pycharm Python 控制台不打印输出

    我有一个从 Pycharm python 控制台调用的函数 但没有显示输出 In 2 def problem1 6 for i in range 1 101 2 print i end In 3 problem1 6 In 4 另一方面 像
  • 如何等到 Excel 计算公式后再继续 win32com

    我有一个 win32com Python 脚本 它将多个 Excel 文件合并到电子表格中并将其另存为 PDF 现在的工作原理是输出几乎都是 NAME 因为文件是在计算 Excel 文件内容之前输出的 这可能需要一分钟 如何强制工作簿计算值
  • 如何使用 Scrapy 从网站获取所有纯文本?

    我希望在 HTML 呈现后 可以从网站上看到所有文本 我正在使用 Scrapy 框架使用 Python 工作 和xpath body text 我能够获取它 但是带有 HTML 标签 而且我只想要文本 有什么解决办法吗 最简单的选择是ext
  • 如何使用装饰器禁用某些功能的中间件?

    我想模仿的行为csrf exempt see here https docs djangoproject com en 1 11 ref csrf django views decorators csrf csrf exempt and h
  • keras加载模型错误尝试将包含17层的权重文件加载到0层的模型中

    我目前正在使用 keras 开发 vgg16 模型 我用我的一些图层微调 vgg 模型 拟合我的模型 训练 后 我保存我的模型model save name h5 可以毫无问题地保存 但是 当我尝试使用以下命令重新加载模型时load mod
  • IRichBolt 在storm-1.0.0 和 pyleus-0.3.0 上运行拓扑时出错

    我正在运行风暴拓扑 pyleus verbose local xyz topology jar using storm 1 0 0 pyleus 0 3 0 centos 6 6并得到错误 线程 main java lang NoClass
  • 在pyyaml中表示具有相同基类的不同类的实例

    我有一些单元测试集 希望将每个测试运行的结果存储为 YAML 文件以供进一步分析 YAML 格式的转储数据在几个方面满足我的需求 但测试属于不同的套装 结果有不同的父类 这是我所拥有的示例 gt gt gt rz shorthand for
  • Abaqus 将曲面转化为集合

    我一直试图在模型中找到两个表面的中心 参见照片 但未能成功 它们是元素表面 面 查询中没有选项可以查找元素表面的中心 只能查找元素集的中心 找到节点集的中心也很好 但是我的节点集没有出现在工具 gt 查询 gt 质量属性选项中 而且我找不到
  • 当玩家触摸屏幕一侧时,如何让 pygame 发出警告?

    我使用 pygame 创建了一个游戏 当玩家触摸屏幕一侧时 我想让 pygame 给出类似 你不能触摸屏幕两侧 的错误 我尝试在互联网上搜索 但没有找到任何好的结果 我想过在屏幕外添加一个方块 当玩家触摸该方块时 它会发出警告 但这花了很长
  • Python - 按月对日期进行分组

    这是一个简单的问题 起初我认为很简单而忽略了它 一个小时过去了 我不太确定 所以 我有一个Python列表datetime对象 我想用图表来表示它们 x 值是年份和月份 y 值是此列表中本月发生的日期对象的数量 也许一个例子可以更好地证明这
  • 如何将 PIL 图像转换为 NumPy 数组?

    如何转换 PILImage来回转换为 NumPy 数组 这样我就可以比 PIL 进行更快的像素级转换PixelAccess允许 我可以通过以下方式将其转换为 NumPy 数组 pic Image open foo jpg pix numpy
  • 循环标记时出现“ValueError:无法识别的标记样式 -d”

    我正在尝试编码pyplot允许不同标记样式的绘图 这些图是循环生成的 标记是从列表中选取的 为了演示目的 我还提供了一个颜色列表 版本是Python 2 7 9 IPython 3 0 0 matplotlib 1 4 3 这是一个简单的代
  • Spark.read 在 Databricks 中给出 KrbException

    我正在尝试从 databricks 笔记本连接到 SQL 数据库 以下是我的代码 jdbcDF spark read format com microsoft sqlserver jdbc spark option url jdbc sql
  • Pandas 与 Numpy 数据帧

    看这几行代码 df2 df copy df2 1 df 1 df 1 values 1 df2 ix 0 0 我们的教练说我们需要使用 values属性来访问底层的 numpy 数组 否则我们的代码将无法工作 我知道 pandas Data

随机推荐

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

    为了防止代码重复 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数据格式转化 一些奇