最近要将神经网络放到编码器中,于是研究了一下C++调用Python的代码。
一、API
主要用到的API如下:
/*PyImport_ImportModule: 加载python模块
*szModuleName: 模块名称
*返回值: 成功加载返回模块指针*/
PyObject *PyImport_ImportModule(const char *szModuleName);
/*PyModule_GetDict: 获取模块字典
*pModule: 模块指针
*返回值: 成功从指定模块获取字典返回字典指针*/
PyObject *PyModule_GetDict(PyObject *pModule);
/*PyDict_GetItemString: 从模块字典中获取指定的对象
*pDict: 被查找的模块字典指针
*key: 要查找的模块中的函数或类名
*返回值: 若找到指定的对象,返回指向它的指针;否则返回NULL*/
PyObject *PyDict_GetItemString(PyObject *pDict, const char *key);
/*PyObject_CallFunction: 调用模块中的函数
*args: 要传给模块函数的参数列表
*返回值: 模块函数的返回值;若模块函数无返回值,该方法返回NULL*/
PyObject *PyObject_CallFunction(PyObject *pFunction, PyObject *args);
二、环境配置
我采用的环境是win10+VS2015+Python3.6.1(Anaconda3)进行配置,配置具体步骤如下
(1)新建一个VS工程
(2)选择平台为“x64”“Release”,注意此处不能选“Debug”,否则会报错,具体原因见:CALLING PYTHON CODE FROM C++
(3)在VS右侧解决方案资源管理器选中工程名称右键->属性->VC++目录(注意配置平台应与运行平台一致),在“包含目录”中添加“E:\Anaconda3\include”,在“库目录”中添加“E:\Anaconda3\libs”(你所安装Anaconda目录下的 include与libs文件夹位置),如果要采用虚拟环境中的python应添加“E:\Anaconda3\envs\tensorflow-gpu\include”与“E:\Anaconda3\envs\tensorflow-gpu\libs”(其中tensorflow-gpu是我取的环境名)
(4)选择链接器->输入,在“附加依赖项”中添加“E:\Anaconda3\libs\python36.lib”(你所安装Anaconda目录下的libs文件夹中相应版本的库文件)
三、运行
首先建立如下cpp文件
#include "Python.h"
#include <iostream>
int main()
{
// Initialize the Python interpreter.
Py_SetPythonHome(L"E:/Anaconda3");
Py_Initialize();
// Create some Python objects that will later be assigned values.
PyObject *pModule, *pDict, *pFunc_add, *pFunc_hello, *pArgs, *pValue;
// Import the file as a Python module.
pModule = PyImport_ImportModule("Sample");
// Create a dictionary for the contents of the module.
pDict = PyModule_GetDict(pModule);
// Get the add method from the dictionary.
pFunc_add = PyDict_GetItemString(pDict, "add");
pFunc_hello = PyDict_GetItemString(pDict, "hello");
// Create a Python tuple to hold the arguments to the method.
pArgs = PyTuple_New(2);
// Convert 2 to a Python integer.
pValue = PyLong_FromLong(2);
// Set the Python int as the first and second arguments to the method.
PyTuple_SetItem(pArgs, 0, pValue);
PyTuple_SetItem(pArgs, 1, pValue);
// Call the function with the arguments.
PyObject_CallObject(pFunc_hello, NULL);
PyObject* pResult = PyObject_CallObject(pFunc_add, pArgs);
// Print a message if calling the method failed.
if (pResult == NULL)
printf("Calling the add method failed.\n");
// Convert the result to a long from a Python object.
long result = PyLong_AsLong(pResult);
// Destroy the Python interpreter.
Py_Finalize();
// Print the result.
printf("Calling Python to find the sum of 2 and 2.\n");
printf("The result is %d.\n", result);
std::cin.ignore();
return 0;
}
其中SetPythonHome后面跟的是Python.exe所在的路径,右键工程生成解决方案。
然后在工程目录下进入文件夹x64->Release,建立一个名为Sample.py的python脚本,脚本内容如下
def hello():
print("hello!")
def add(a, b):
return a+b
之后保存,运行工程就可以实现C++调用Python了