C++调用Python3详细记录

本文详细介绍了如何在C++程序中调用Python3接口,包括调用函数、类、处理特殊返回对象(如Map)以及传递OpenCV的Mat图像。在CMake中添加Python3动态链接库后,通过Python C接口实现了C++调用Python深度学习模型,虽然牺牲了效率,但提供了一种实用的方法。
摘要由CSDN通过智能技术生成

通过在C++程序调用Python3所提供的C接口可以实现调用Python程序所实现的功能。在C++调用深度学习训练好的模型时,如果不使用一些部署手段,这种C++调用Python接口的方式虽然大大牺牲了效率,但是可以说是也是一种取巧的方法。这里记录一下C++如何去调用Python3的接口,作为一个总结。
操作系统:Ubuntu16.04
构建工具:CMake

要想在 C++ 中调用 Python3 ,必须在 Cmake 中添加一些 Python3 的动态链接库:
可以在 include_directories中加入:

 /usr/include/python3.5
 /usr/lib/python3/dist-packages/numpy/core/include/numpy

target_link_libraries中加入:

 /usr/lib/x86_64-linux-gnu/libboost_python-py35.so
 /usr/lib/x86_64-linux-gnu/libstdc++.so.6
 /usr/lib/x86_64-linux-gnu/libpython3.5m.so

1. 调用Python3中的函数

int testFunction1(){
   
    Py_Initialize();
    if(!Py_IsInitialized()){
   
        cout << "[Error] Init error" << endl;
        return -1;
    }

    string change_dir = "sys.path.append('../scripts')";
    PyRun_SimpleString("import sys");
    PyRun_SimpleString(change_dir.c_str());

    PyObject *pModule = PyImport_ImportModule("testFunction");

    if (pModule == nullptr){
   
        cout <<"[Error] Import module error" << endl;
        return -1;
    }

    cout << "[INFO] Get Module" << endl;

    PyObject *pFunction = PyObject_GetAttrString(pModule, "func");
    if (pFunction == nullptr){
   
        cout << "[Error] Import function error" << endl;
        return -1;
    }

    cout << "[INFO] Get Function" << endl;
    PyObject *args = PyTuple_New(1);
    PyObject *args1 = PyUnicode_FromString("../air.jpg");

    PyTuple_SetItem(args, 0, args1);

    PyObject *pRet = PyObject_CallObject(pFunction, args);
    int res = 999;
    if (pRet){
   
        PyArg_Parse(pRet,"i", &res);
        cout << res << endl;
    }

    Py_DecRef(pModule);
    Py_DecRef(pFunction);
    Py_DecRef(args);
    Py_DecRef(args1);
    Py_DecRef(pRet);
    Py_Finalize();
    return 1;
}

代码中值得注意的是有很多固定写法:
Py_Initialize():Python的初始化
PyRun_SimpleString:执行简单的Python语句
Py_DecRef: 释放资源
Py_Finalize: 结束Python

其中../scripts是存放Python代码的路径,路径是相对于c++ bin文件的路径而言。
PyImport_ImportModule("testFunction");调用了名为 testFunction 的 py 程序。

PyObject *pFunction = PyObject_GetAttrString(pModule, "func2");

得到python程序中的 函数func的PyObjet指针 。

PyObject *args = PyTuple_New(1);
PyObject *args1 = PyUnicode_FromString("../air.jpg");

PyTuple_SetItem(args, 0, args1);

这里,是封装函数参数,放到一个Py元组中。

PyObject *pRet = PyObject_CallObject(pFunction, args);

这里是调用了刚才 func函数,并传递了参数,同时得到一个返回对象。程序利用了PyArg_Parse(pRet,"i", &res);进行对 pRet 的 Py 对象进行解析,解析成 int 类型。由此得到正确的返回值。
可以看一下testFunction.py程序:

import numpy as np
import tensorflow as tf
import os
from PIL import Image

def func(pic):
        modelDir = "/home/tyl/Code/Cprojects/TestDemo/TestCppPython/TestPython3/model"
        sess = tf.Session()
        saver = tf.train.import_meta_graph(os.path.join(modelDir,"model.ckpt.meta"))
      
  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值