C++调用python (2.7版本)
由于个人偏好喜欢用python写代码,尤其是数据处理等,最近想试试在VS2013里,直接调用python中的曲线拟合函数。作为小白,由于之前完全没接触过,就一直找网上找教程,折腾了2小时总算是搞定了。接下来,为了方便和我一样的初学者学习,我将具体的配置过程详细写下来,写得不好,还望指教。(一个月后:现在看来,不建议这样调用,个人觉得意义不大,若想学一下,可以继续浏览;否则还是放弃直接多看会儿C++,还是能将python代码直接改成C++代码的,不用调用)
一、 最终结果展示:
以下代码是main.cpp
-
#include
<iostream>
-
#include
<Python.h>
-
using namespace std;
-
-
-
extern "C"
-
{
-
#include "Python.h"
-
}
-
//调用输出"Hello Python"函数
-
void Hello()
-
{
-
Py_Initialize();//调用Py_Initialize()进行初始化
-
PyObject * pModule = NULL;
-
PyObject * pFunc = NULL;
-
pModule = PyImport_ImportModule("Test001");//调用的Python文件名
-
pFunc = PyObject_GetAttrString(pModule, "Hello");//调用的函数名
-
PyEval_CallObject(pFunc, NULL);//调用函数,NULL表示参数为空
-
Py_Finalize();//调用Py_Finalize,和Py_Initialize相对应的.
-
}
-
//调用Add函数,传两个int型参数
-
void Add()
-
{
-
Py_Initialize();
-
PyObject * pModule = NULL;
-
PyObject * pFunc = NULL;
-
pModule = PyImport_ImportModule("Test001");//Test001:Python文件名
-
pFunc = PyObject_GetAttrString(pModule, "Add");//Add:Python文件中的函数名
-
//创建参数:
-
PyObject *pArgs = PyTuple_New(2);//函数调用的参数传递均是以元组的形式打包的,2表示参数个数
-
PyTuple_SetItem(pArgs, 0, Py_BuildValue("i", 6));//0--序号,i表示创建int型变量
-
PyTuple_SetItem(pArgs, 1, Py_BuildValue("i", 8));//1--序号
-
//返回值
-
PyObject *pReturn = NULL;
-
pReturn = PyEval_CallObject(pFunc, pArgs);//调用函数
-
//将返回值转换为int类型
-
int result;
-
PyArg_Parse(pReturn, "i", &result);//i表示转换成int型变量
-
cout
<< "6 + 8 = " << result << endl;
-
Py_Finalize();
-
}
-
int main(int argc, char** argv)
-
{
-
cout << "调用
Test001.py中的
Hello函数
..." <<
endl;
-
Hello();
-
cout << "\n调用Test001.py中的Add函数..." << endl;
-
Add();
-
system("pause");
-
return 0;
-
}
-
接着是调用的函数,也就是Test001.py文件中内容:
-
def Hello():
-
print(
"Hello Python")
-
-
def Add(a, b):
-
return a+b
最后,运行结果如下:
二、环境配置
那么究竟如何调用呢?我的电脑环境:Win7(64位)+anaconda2.4(python2.7.13)+VS2013,其实我习惯用anaconda3.4.2(python3.5),起初用C++去调用python3.5,遇到太多的坑,实在不行,按照同样的方法试了一下python2.7,真的没问题,欲哭无泪。。。下面我再调用一次,具体步骤如下:
1、python2.7的安装(anaconda2-4.4.0-Windows-x86_64),并配置环境变量(否则报错no module named sites);
2、将Python加到VS2013的详细过程:
(1)桌面上新建一个文件夹,如test,再建立一个空的Win32控制台项目,创建main.cpp保存test文件夹中,此时的代码会报错,因为还没导入python2.7的头文件路径与库文件的路径;
(2)找到python2.7的安装路径:(我的是:D:\python2.7\anaconda2.4),找到路径下的include与libs两个文件夹,将libs中的python27.lib复制并更名为python27_d.lib;
(3)x64平台&python2.7头文件与库文件的路径配置:
X64平台:生成->配置管理器->新建;
右击进入属性设置页C/C++->常规->附加包含目录,输入 D:\python2.7\anaconda2.4\include
再找到链接器->常规->附加目录项,输入 D:\python2.7\anaconda2.4\libs
结果如下图所示:
(4)生成解决方案,显示:
========== 生成: 成功 1 个,失败 0 个,最新 0 个,跳过 0 个 ==========
(5)别激动,先运行,你会发现,报错啦!!!无法启动此程序,因为计算机中丢失python27.dll。尝试重新安装该程序以解决此问题。怎么办呢?
将python安装路径下的python27.dll拷贝到桌面test文件夹中的x64文件夹中的Debug目录下
(如:C:\Users\Zhangwei\Desktop\test\ConsoleApplication1\x64\Debug):
(6)重新生成解决方案,并运行,还是报错了,气不气?如下图:
(7)之所以报错,是因为还未添加Test001.py,将该文件添加到Debug路径下
(如:C:\Users\Zhangwei\Desktop\test\ConsoleApplication1\x64\Debug):
(8)重新生成解决方案,再次运行,很激动吧,终于成功咯!!!
注意:建议别按照上面的方式更改坏境变量,否则在pycharm中选择相应的python2.7版本时候,会报错。
相信走到这里,C++调用python应该是问题不大,至少语法上是没有问题的,接下来我再说说我遇到的bug:
由于我习惯用python3.5,之前用VS2013调用python3.5,若按照上面这一套流程走下来,还是无法运行,真的是心累!我怀疑是anaconda3.4.2(python3.5.2)里面的libs中的文件只有三个,是不是有缺失?
后来 经过查找相关资料,总算是找到了调用解决方案,现在总结如下:
C++调用python (3.5版本)
VS2013+python3.5
一、最终结果展示
-
#include <iostream>
-
#include <Python.h>
-
using
namespace
std;
-
-
//extern "C"
-
//{
-
//#include "Python.h"
-
//}
-
-
// 练习一:如何使用C++调用函数python中的参数返回函数?
-
int great_function_from_python(int a)
-
{
-
Py_SetPythonHome(
L"C:/Users/Zhangwei/Anaconda3");
//配置python3的环境变量
-
Py_Initialize();
-
int res;
-
PyObject *pModule, *pFunc;
-
PyObject *pArgs, *pValue;
-
-
/* import */
-
//pModule = PyImport_Import(PyString_FromString("great_module"));
-
pModule = PyImport_ImportModule(
"great_module");
-
-
/* great_module.great_function */
-
pFunc = PyObject_GetAttrString(pModule,
"great_function");
-
-
/* build args */
-
pArgs = PyTuple_New(
1);
-
PyTuple_SetItem(pArgs,
0, Py_BuildValue(
"i", a));
-
-
/* call */
-
PyObject *pReturn =
NULL;
-
pReturn = PyEval_CallObject(pFunc, pArgs);
-
-
PyArg_Parse(pReturn,
"i", &res);
//i表示转换成int型变量
-
return res;
-
-
Py_Finalize();
-
}
-
-
-
// 练习二:如何使用C++直接运行hello!
-
void print()
-
{
-
Py_SetPythonHome(
L"C:/Users/Zhangwei/Anaconda3");
//配置python3的环境变量
-
//Py_SetProgramName(argv[0]);
-
Py_Initialize();
-
PyRun_SimpleString(
"print('Hello Python!')\n");
-
Py_Finalize();
-
}
-
-
-
// 练习三:如何使用C++调用curveFitting.py中的函数Hello
-
void Hello() //调用输出"Hello Python"函数
-
{
-
Py_SetPythonHome(
L"C:/Users/Zhangwei/Anaconda3");
//配置python3的环境变量
-
Py_Initialize();
//调用Py_Initialize()进行初始化
-
-
if (!Py_IsInitialized())
-
{
-
printf(
"初始化失败!");
-
}
-
PyObject * pModule =
NULL;
-
PyObject * pFunc =
NULL;
-
pModule = PyImport_ImportModule(
"curveFitting");
//调用的Python文件名
-
pFunc = PyObject_GetAttrString(pModule,
"Hello");
//调用的函数名
-
PyEval_CallObject(pFunc,
NULL);
//调用函数,NULL表示参数为空
-
Py_Finalize();
//调用Py_Finalize,和Py_Initialize相对应的.
-
}
-
-
-
//练习四:如何使用C++调用curveFitting.py中的函数Add
-
void Add() //调用Add函数,传两个int型参数
-
{
-
-
Py_SetPythonHome(
L"C:/Users/Zhangwei/Anaconda3");
//配置python3的环境变量
-
//第一步:调用Py_Initialize()进行初始化
-
Py_Initialize();
-
//检查初始化是否完成
-
if (!Py_IsInitialized())
-
{
-
printf(
"初始化失败!");
-
}
-
-
-
//py文件及函数声明变量
-
PyObject * pModule =
NULL;
-
PyObject * pFunc =
NULL;
-
-
//加载
-
-
try
-
{
-
pModule = PyImport_ImportModule(
"curveFitting");
//curveFitting:Python文件名
-
}
-
catch (...)
-
{
-
printf(
"pModule加载异常!");
-
}
-
if (pModule ==
NULL)
-
{
-
printf(
"pModule加载失败!");
-
}
-
-
pFunc = PyObject_GetAttrString(pModule,
"Add");
//Add:Python文件中的函数名
-
-
-
//创建参数:
-
PyObject *pArgs = PyTuple_New(
2);
//函数调用的参数传递均是以元组的形式打包的,2表示参数个数
-
PyTuple_SetItem(pArgs,
0, Py_BuildValue(
"i",
6));
//0--序号,i表示创建int型变量
-
PyTuple_SetItem(pArgs,
1, Py_BuildValue(
"i",
8));
//1--序号
-
-
-
//返回值
-
PyObject *pReturn =
NULL;
-
pReturn = PyEval_CallObject(pFunc, pArgs);
//调用函数
-
-
-
//将返回值转换为int类型
-
int result;
-
PyArg_Parse(pReturn,
"i", &result);
//i表示转换成int型变量
-
cout <<
"6 + 8 = " << result <<
endl;
-
Py_Finalize();
-
}
-
-
-
int main(int argc, char *argv[]) {
-
-
//练习一:
-
printf(
"运行结果为:%d\n", great_function_from_python(
2));
-
-
//练习二
-
printf(
"\n");print();
-
-
//练习三
-
printf(
"\n");
-
cout <<
"调用curveFitting.py中的Hello函数..." <<
endl;
-
Hello();
-
-
//练习四
-
printf(
"\n");
-
cout <<
"\n调用curveFitting.py中的Add函数..." <<
endl;
-
Add();
-
-
system(
"pause");
-
return
0;
-
最后的运行结果如下:
二、环境配置
如果试过第一种方法的朋友会发现,直接更改系统环境变量,会导致原本的python2.7运行始终报错。以python3.5为例:需要单独将anaconda3下面的,include文件夹里面的头文件、libs文件夹里面的库函数,以及python35.dll(动态链接库文件)都单独拷贝出来,至于怎么设置,怎么放,咱们慢慢来。
1、桌面新建一个文件夹,取名为test_python35;
2、将anaconda3下面的,include文件夹、libs文件夹都拷贝到test_python35文件夹中;
3、打开VS2013,新建一个项目,选好路径,桌面的文件夹test_python35里面的内容如下:
4、新建一个main函数如上展示图所示,接下来需要配置环境变量
(1)添加头文件
(2)添加库文件
(3)代码中配置python3的环境变量
Py_SetPythonHome(L"C:/Users/Zhangwei/Anaconda3");//配置python3的环境变量
5、生成解决方案,不会报错,但肯定没有结果,因为还没有添加动态链接库文件调用的python原函数。具体做法:在生成的Debug路径下添加python35.dll(anaconda3的安装路径里面有)、调用的python原函数(curveFitting.py与great_module.py),如下图所示
6、重新生成解决方案,再次运行即可,于是便得到了最开始的结果图。
三、C++调用python的代码解读
这部分多查阅相关文件,很快就能上手的 ,具体就不说了,网上一大把,最后祝大家学业有成。
PS:以上代码已打包,下载链接为C++调用python3.5或者http://download.csdn.net/download/zichen_ziqi/10236034。
参考文献
1. C++调用python实例:http://blog.csdn.net/u012983289/article/details/55194714
2. VS平台简单实用C++调用python3.5的方法:http://blog.csdn.net/polley88/article/details/54971560
3. python实例浅谈三之C++与python相互调用: http://blog.csdn.net/taiyang1987912/article/details/44779719
4. C++调用python3:http://blog.csdn.net/lisy14/article/details/64498796
5. C++调用python3:http://blog.csdn.net/u014794992/article/details/52901219