最近一直思考如何将弥补c++中的数据挖掘算法不足的问题,毕竟现在大家都图省事的说。于是现有语言中属python的库文件最多,且简单的胶水语言。那么通过c++调用Python会不会很方便呢?所以本着这样的想法我们研究一下。
1、对python目录下的文件检查
首先你得安装python 我这里是python3.4,打开安装目录下的include文件夹,也就找到了python.h,如图圈出!
然后打开python34下的libs文件夹,找到python34.lib,复制并粘贴更改名称为python34_d.lib
好滴,这样一来文件就检查 准备完毕了。
2、C++环境的配置(VS2013)
首先新建项目---空项目命名---添加源文件cpp。对项目进行右键属性,C/C++、常规、对附加包含目录添加D:\Python34\include路径(就是第一步操作检测的文件夹添加路径就行了)
然后在链接器---输入---附加依赖项,手动添加python34.lib
最后在链接器---常规---附加库目录,添加D:\Python34\libs(也就是第一步操作中检测的文件夹)
这时候你再在cpp源文件中添加#include<python.h>,就显示Ok了,找到头文件了
3、编写python文件
我这里写的是
def Hello():
print("Hello Python")
def Add(a, b):
import numpy as np
print(np.pi)
return a+b
注意的是,以调用函数的形式,模块库的调用写到def函数结构中去;得到的python(.py)文件请加到C++的main文件所在文件夹中去!
4、编写C++,实现C++调用python文件
直接上代码,C++的函数实现对python中的两个函数进行重新构造(初始化、传参、运行、输出、结束)
#include <Python.h>
#include <iostream>
//#include <math.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相对应的.
}
//调用py文件中的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;
}