这里要隆重的写一下C++调用python遇到的各种坑,搞了好久,终于成功了!
平台环境:Windows7++Vs2017+python3.7.2
第一步:安装vs2017
vs2017安装比较人性化,可以下载引导文件进行在线安装,我下载的是社区版,安装出现的问题见上一篇博客,https://blog.****.net/Darling100/article/details/105048755。
我是先卸载的vs2010再安装的2017,害怕卸载不干净有残给以后造成隐患。所以采用的手动卸载,使用iobituninstaller_lsb,参照博客:https://blog.****.net/heng_2679/article/details/39024285 ,加之公司网络较慢,解决安装过程中的各种问题,安装了小一天的时间。
安装vs2017选择不需要安装很多组件,我只选择了Windows平台开发和C++桌面开发,还有一个工具包。安装完成Vs2017后登陆自己的微软账号,也可以不登录。进行页面设置,也可以以后设置。
第二步:VS2017配置
新建项目project2,在项目属性中进行如下配置:
(1)常规里面,windows sdk版本选择10.0.17763.0,。
(2)
选择C/C++附加目录添加python的安装目录。
查找安装目录的方法是,打开cmd,import sys,sys.path,点击enter键即可。下面是我自己的python安装目录:
(3)选择链接器,常规里面添加库目录,如下图所示:
(4)链接器输入选项,添加附加依赖项。
第三步:生成python37_d.lib
配置vs2017参照下面博客:https://blog.****.net/nanguabing007/article/details/89394541?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task,生成python37_d.lib,把生成的该文件放在python安装目录libs下。
第四步:在project2添加代码如下:
#include <Python.h>
#include<iostream>
using namespace std;
int main()
{
Py_SetPythonHome(L"C:\\Users\\Administrator\\Appdata\\Local\\Programs\\Python\\Python37\\");//这里地址一定要写对啊!
/**
这句语句是在添加python.exe所在路径,不添加虽然编译没有问题,但是会在运行时出现
Fatal Python error: initfsencoding: unable to load the file system codec
ModuleNotFoundError: No module named 'encodings'
这种很无厘头的错误
**/
Py_Initialize();//使用python之前,要调用Py_Initialize();这个函数进行初始化
if (!Py_IsInitialized())
{
printf("初始化失败!");
return 0;
}
else {
PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path.append('./')");//这一步很重要,修改Python路径
PyObject * pModule = NULL;//声明变量
PyObject * pFunc = NULL;// 声明变量
pModule = PyImport_ImportModule("hello");//这里是要调用的文件名hello.py
if (pModule == NULL)
{
cout << "没找到该Python文件" << endl;
}
else {
pFunc = PyObject_GetAttrString(pModule, "add");//这里是要调用的函数名
PyObject* args = Py_BuildValue("(ii)", 28, 103);//给python函数参数赋值
PyObject* pRet = PyObject_CallObject(pFunc, args);//调用函数
int res = 0;
PyArg_Parse(pRet, "i", &res);//转换返回类型
cout << "res:" << res << endl;//输出结果
}
Py_Finalize();//调用Py_Finalize,这个根Py_Initialize相对应的。
}
return 0;
}
第五步:python代码如下:
def add(a,b):
print ("These consequences are from Python code.")
print ("a = " + str(a))
print ("b = " + str(b))
print ("ret = " + str(a+b))
return a + b
python文件放置在debug文件夹下,与.exe文件同目录,如下图:
第六步:生成-生成解决方案,调试-开始执行(不调试),如果幸运,就成功了。很不幸我没有成功。
坑1:编译生成解决方案失败,报错,stdint.h *****unicode***
解决方法使用notepad++编码保存为:
坑2:d:\windows kits\10\include\10.0.17763.0\ucrt\inttypes.h(27): error C3646: “类似这种错误一大堆。
把inttypes.h放在报错的文件夹下,并更改文件内容:参照博客:https://blog.****.net/u010377372/article/details/78470824?utm_source=blogxgwz6
#include<stdint.h>更改为
#include "stdint.h"
坑3 编译不出错,但是运行exe文件时找不到python37_d.dll文件,在前述生成的文件中找到该文件,放置在windows\SysWOW64文件夹下。该文件夹是Windows操作系统的子系统,存放运行32位程序所必须的组件。一开始以为放在system32下面,一直不对。system32是Windows 操作系统的系统文件夹。是操作系统的中枢。存放运行64位程序所必须的组件(可以粗暴的理解为dll)
坑4:出现Fatal Python error:initfsencoding:unable to load the file system codec
ModuleNotFoundError:No module named 'encodings'
Current thread 0x00000ba4 (most resent call first):
这是因为引用的python运行地址不对,检查代码中的python路径,发现警告通用字符名不正确。解决方法是把路径中的\前面都加上\,问题解决。
运行成功。
以上记录遇到的大坑,一些小问题相信你可以查找大牛的微博能够解决。感谢以上引用微博的作者,谢谢你们的分享。