C++调用Python中的函数

VS2010的配置(设置编译环境)

1. 在python安装目录(如F:\Program Files\Python_3.5.3)下找到include和libs文件夹,将它们拷贝到sln同级目录下。

进入项目 > 属性 > 配置属性 > VC++目录 > 库目录,添加..\libs

进入项目 > 属性 > C/C++ > 常规 > 附加包含目录,添加..\include

C++代码

void DetactImage(CString image_name, CString model_path)
{
    try{
        Py_Initialize();
        if (!Py_IsInitialized())
            printf("Initialize Error!\n");
        PyEval_InitThreads();        
        // 载入module
        PyObject * pModule = NULL;
        pModule = PyImport_ImportModule("demo");//调用的Python文件名
        if (!pModule)
        {
            cout<<"cannot open module!"<<endl;
            Py_Finalize();
            return;
        }
        // 将module中的方法以字典形式读入
        PyObject *pDict = NULL;
        pDict = PyModule_GetDict(pModule);
        if (!pDict)
        {
            printf("PyModule_GetDict Error!\n");
            return;
        }
        // 在方法字典中通过名字获取对应的方法
        PyObject *pFunc = NULL;
        pFunc = PyDict_GetItemString(pDict, "image_detact");
        if (!pFunc || !PyCallable_Check(pFunc))
        {
            printf("Can't find function[image_detact]\n");
            getchar();
            return;
        }
        // 设置方法的参数
        PyObject *pArgs = NULL;
        pArgs = PyTuple_New(2);
        PyTuple_SetItem(pArgs, 0, Py_BuildValue("s", image_name));
        PyTuple_SetItem(pArgs, 1, Py_BuildValue("s", model_path));
        //调用方法add,传入参数 float
        PyObject_CallObject(pFunc, pArgs);
    }
    catch(exception& e)
    {
        cout << "Standard exception: " << e.what() << endl;
    }
}

如果Python返回的是数组,可以使用以下方式获取数据

PyObject *pResult = PyObject_CallObject(pFunc, pArgs);
if (PyList_Check(pResult))
{ //检查是否为List对象
     int SizeOfList = PyList_Size(pResult);//List对象的大小,这里SizeOfList = 3
     for (int Index_i = 0; Index_i < SizeOfList; Index_i++)
    {
        PyObject *ListItem = PyList_GetItem(pResult, Index_i);//获取List对象中的每一个元素
        int NumOfItems = PyList_Size(ListItem);//List对象子元素的大小,这里NumOfItems = 3
         for (int Index_k = 0; Index_k < NumOfItems; Index_k++)
        {
            PyObject *Item = PyList_GetItem(ListItem, Index_k);//遍历List对象中子元素中的每个元素
            char *cRst;
            PyArg_Parse(Item, "s", &cRst);
            cout << cRst << " "; //输出元素
             //Py_DECREF(Item); //释放空间
         }
         //Py_DECREF(ListItem); //释放空间
     }
     cout << endl;
}
else 
{
    cout << "Not a List" << endl;
}

更多返回方式可参考以下链接

https://blog.csdn.net/stu_csdn/article/details/69488385

说明:

引入#include <numpy/arrayobject.h>时,如果出现“无法解析的外部符号 __imp__Py_NegativeRefcount”和“无法解析的外部符号__imp__Py_RefTotal”的错误,可以尝试修改两个头文件

1、注释掉object.h第56行

//#define Py_TRACE_REFS

2、pyconfig.h 375行

//# define Py_DEBUG

以上两个宏定义注释掉以后重新编译 问题解决

Python代码

import cv2
import matplotlib.pyplot as plt
import tensorflow as tf

def image_detact(image_name, model_path):
    print (image_name)
    print (model_path)
    im = cv2.imread(image_name)
    cv2.imshow('image', im)
    cv2.waitKey(0)
    ...