Skip to content

在C++中调用Python

因为工作原因,算法部分是python写的,之前一直用rpc的方法来调用python函数,我感觉这种方法有一点不够简洁(?),于是打算引入Python.h的库来做这一工作,所以就有了晚上的实操。

不多说,上代码。

#include <iostream>
#include <Python.h>

int main()
{
    //_putenv("PYTHONHOME=D:/Users/hoshinokun/miniconda3/envs/python_3_7");

    Py_Initialize();
    if (!Py_IsInitialized()) {
        std::cout << "python init fail" << std::endl;
        return 0;
    }

    PyRun_SimpleString("import sys");
    PyRun_SimpleString("sys.path.append('./')");

    PyObject* pModule = PyImport_ImportModule("test2");
    if (pModule == nullptr)
    {
        PyErr_Print();
        std::exit(1);
    }

    PyObject* pFunc = PyObject_GetAttrString(pModule, "press");

    PyObject* pReturn = PyEval_CallObject(pFunc, NULL);

    bool nResult;

    PyArg_Parse(pReturn, "i", &nResult);

    Py_Finalize();
    std::cout << "return result is " << nResult << std::endl;
    std::cout << "Hello World!\n";
}

其中有几个注意的点。

  1. 如果你的python库不在PATH里面,你需要用c的函数_putenv来将你的python路径加到PYTHONHOME的里面,否则你的函数初始化Py_Initialize时候会报错直接弹出。
  2. 在vs调试的时候,默认路径是vs源码的路径而不是应用程序的路径,你需要把test2.py文件和你的cpp代码放在一起
  3. PyImport_ImportModule的时候,一开始我一直报错,pModule一直为NULL,所以这个时候引入了PyErr_Print函数,其可以输出一个python标准错误,你就可以在命令行里面看到你具体是什么样的错误
  4. PyErr_Print函数输出了一个cv2引用错误,查了一下资料发现,python的库是没有_d的调试库的,在运行调试版本的程序的时候,会因为找不到调试库而直接报错弹出找不到库,所以需要在Release环境下面去调试程序

Published in技术探究

Be First to Comment

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注