Python语言—C/C++&python合♂体开发
小标 2018-10-09 来源 : 阅读 1177 评论 0

摘要:本文主要向大家介绍了Python语言—C/C++&python合♂体开发,通过具体的内容向大家展示,希望对大家学习Python语言有所帮助。

本文主要向大家介绍了Python语言—C/C++&python合♂体开发,通过具体的内容向大家展示,希望对大家学习Python语言有所帮助。

之前开发python一直都是用C++的system()调用脚本执行某些相关处理

然而需要返回值时,却感觉到了相当的蛋疼。即使我们可以强行夺取system的返回值(py代码里sys.exit(0))来实现整型的返回值

但其也不是一个长久之计。更何况如果我们需要其它类型的返回值呢?比如说最常见的字符串类型。那就只能让两者关联

下面我们就来看看   如何让python和c++完美的结合在一起~


①我们先建立一个python脚本,比如说实现A+B的功能


#retStr_test function import sysdef retStr_test(a,b): print "MDZZ:"+str(a)+"+"+str(b)+"="+str(a+b)+"!"return "MDZZ:"+str(a)+"+"+str(b)+"="+str(a+b)+"!"#retStr_test(int(sys.argv[1]),int(sys.argv[2]))



最后一行为测试时的入口,关联C++程序时请注释掉~




好,确认我们python里的函数retStr_test没有问题后,进行下一步


②配置python环境

导入python相关的头文件与lib包



③如果出现【无法打开文件“python27_d.lib】报错的话

修改pyconfig.h文件


将这里的python27_d.lib修改为python27.lib,也可以复制一份python27.lib名为python27_d.lib



/* For an MSVC DLL, we can nominate the .lib files used by extensions */#ifdef MS_COREDLL# ifndef Py_BUILD_CORE /* not building the core - must be an ext */# if defined(_MSC_VER) /* So MSVC users need not specify the .lib file in their Makefile (other compilers are generally taken care of by distutils.) */# ifdef _DEBUG# pragma comment(lib,"python27.lib")# else# pragma comment(lib,"python27.lib")# endif /* _DEBUG */# endif /* _MSC_VER */# endif /* Py_BUILD_CORE */#endif /* MS_COREDLL */




④如果编译时出现一些外部引用报错的话,例如:



修改object.h



注释掉这个就好了


/* Py_DEBUG implies Py_TRACE_REFS. */#if defined(Py_DEBUG) && !defined(Py_TRACE_REFS)//#define Py_TRACE_REFS#endif



这些是由于debug问题,你也可以选择release神马的……


接下来C++代码开发

代码中引入python头文件#include "Python.h" 

介绍一些相应函数:

PyObject python对象的结构体,我们与python交互时都要以这个为类型

Py_Initialize(); 初始

Py_Finalize(); 关闭

Py_IsInitialized()检查初始是否成功

PyRun_SimpleString("import sys"); 
PyRun_SimpleString("sys.path.append('./')"); 添加当前路径

PyImport_Import(PyObject *pName);载入脚本

PyString_FromString(string s);为了配合上一个函数,将str转换为PyObject

PyModule_GetDict(PyObject *pName)通过引入的模块转为一个字典(其实也是PyObject)

PyDict_GetItemString(PyObject *pDict, string s);上一个转换完了字典对象,以及函数名s

PyTuple_New(int n); 参数个数

PyTuple_SetItem 参数进栈,具体格式见代码注释

PyObject_CallObject(PyObject *pFunc, PyObject *pArgs)调用脚本,返回PyObject类型

PyArg_Parse(PyObject *result, "s", &strRet);格式转换



完整代码如下:


// call_py_test.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"#include "Python.h" #include <string>#include <iostream>using namespace std;int main(int argc, char** argv) { // 初始化Python  //在使用Python系统前,必须使用Py_Initialize对其  //进行初始化。它会载入Python的内建模块并添加系统路  //径到模块搜索路径中。这个函数没有返回值,检查系统  //是否初始化成功需要使用Py_IsInitialized。  Py_Initialize(); // 检查初始化是否成功  if ( !Py_IsInitialized() ) { return -1; } // 添加当前路径  //把输入的字符串作为Python代码直接运行,返回0  //表示成功,-1表示有错。大多时候错误都是因为字符串  //中有语法错误。  PyRun_SimpleString("import sys"); PyRun_SimpleString("sys.path.append('./')"); PyObject *pName,*pModule,*pDict,*pFunc,*pArgs; // 载入名为pytest的脚本  pName = PyString_FromString("pytest"); //我的脚本直接放在了debug下 pModule = PyImport_Import(pName); if ( !pModule ) { printf("can't find pytest.py"); getchar(); return -1; } pDict = PyModule_GetDict(pModule); if ( !pDict ) { return -1; } // 找出函数名为retStr_test的函数  pFunc = PyDict_GetItemString(pDict, "retStr_test"); if ( !pFunc || !PyCallable_Check(pFunc) ) { printf("can't find function [retStr_test]"); getchar(); return -1; } // 参数进栈  *pArgs; pArgs = PyTuple_New(2); //  PyObject* Py_BuildValue(char *format, ...)  //  把C++的变量转换成一个Python对象。当需要从  //  C++传递变量到Python时,就会使用这个函数。此函数  //  有点类似C的printf,但格式不同。常用的格式有  //  s 表示字符串,  //  i 表示整型变量,  //  f 表示浮点数,  //  O 表示一个Python对象。  int arg1=233;       //定义第一个参数 int arg2=250;       //定义第二个参数  PyTuple_SetItem(pArgs, 0, Py_BuildValue("i",arg1)); PyTuple_SetItem(pArgs, 1, Py_BuildValue("i",arg2)); // 调用Python函数  char* strRet; PyObject* result=PyObject_CallObject(pFunc, pArgs); //返回值类型转换 PyArg_Parse(result, "s", &strRet); cout<<"strRet="<<strRet<<endl; Py_DECREF(pName); Py_DECREF(pArgs); Py_DECREF(pModule); // 关闭Python  Py_Finalize(); system("pause"); return 0;}





部分内容学习与//blog.chinaunix.net/uid-20564848-id-73553.html


VS2010完整项目工程关于python关联c++开发的demo   下载地址://download.csdn.net/detail/sm9sun/9696866



虽然我们实现了python与c++的交互,但是是否采用这种手段还要根据具体情况分析。

比如说其调用的性能、PyObject对象强转后的准确性等一系列问题都需要我们长期去测试。

个人认为,如果交互次数不是很多的话,也可以考虑以读写文本的形式进行参数的交互

这样做的好处:

①免去了配置环境及其相关开发的繁琐流程

②内容传递相对来说较安全准确

③其内容可以留存,相当于log

④完全没有语言、平台等限制


本文由职坐标整理并发布,希望对同学们学习Python有所帮助,更多内容请关注职坐标编程语言Python频道!

本文由 @小标 发布于职坐标。未经许可,禁止转载。
喜欢 | 1 不喜欢 | 0
看完这篇文章有何感觉?已经有1人表态,100%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程