混合编程杂谈
此文抛砖引玉,仅作记录,希望广大网友多多指正,谢谢!
最近接触了混编的项目,项目是02年开发的,当时使用的是VC6.0+TCL脚本,VC负责前台的界面显示,后台全部用TCL实现,由于公司规定不能截图出来,望大家海涵,大概描述一下工具的功能,主要用于检查某种负责通信的服务是否配置、运行等正常。大体功能如下:左边是局点的控制描述,主要记录有局点名称、局点IP、连接方式、用户名密码、是否使用内置FTP等信息,右边是每一个局点要执行的任务配置项,主要分为两个大项:健康检查和信息收集。
最近有一个新的需求是给现有的工具添加一个导入导出的功能,主要就是左边的这些操作,方便在配置一次后,在不同的PC上运行相同的工具不需要重新再次配置,只需要将要来配置好的执行一次导入导出就可以执行检查操作。由于本人再次之前没有接触过VC的MFC框架,所以想通过其他的方式处理这个新的需求,目前在网上找到一些可以参考的例子:
C++与python混合编程
- (http://blog.sina.com.cn/s/blog_6ec980ee0101cgax.html)
- (http://www.cnblogs.com/lvpengms/archive/2010/02/03/1663071.html)
- (http://www.cnblogs.com/yincheng01/archive/2010/04/24/2213259.html)
java和jpython混合编程
- (http://blog.csdn.net/hong0220/article/details/40831605)
C#与python混合编程
- (http://www.cnblogs.com/chaosimple/p/4035693.html)
但是看起在运行的过程中都离不开python解释器,这让人很头疼也很郁闷呀,因为我不能要求需要使用这个工具的的人都安装python的解释器,而且不同的人安装的解释器版本不同,有可能出现更多的问题,这些都不是我一个小小的开发能控制的。所以我的想法是我能不能把python的运行环境集成起来形成一个封闭的工具系统而不依赖具体的环境,就像是java开发的软件独立的携带自己的jvm独立运行。
找到一个C++与python混合编程操作的例子:
一、环境搭建
- 安装python2.7(其他版本的python环境不影响下面的操作,只是注意区分不同的设置)。
- 配置vs2013项目(python自带的python27.dll为release版本,所以vs2013项目也必须调整为release,如果需要debug版本可以下载python源码自己编译,也可以在网上找找有没有好心人编译好的。)
- 使用VS2013创建C++工程,创建完成后设置工程的属性引用头文件和静态库等,具体设置如下图所示:
① C/C++ ----> 常规 ---> 附件库包含目录,加入python头文件目录
② 连接器 ---> 常规 --->附件库目录。加入python库文件目录
③ 连接器 ---> 输入 ---> 附加依赖项。加入python库文件名
二、代码实现
1、嵌套调用
1 // test_C_python.cpp : 定义控制台应用程序的入口点。 2 // 3 4 #include "stdafx.h" 5 #include "Python.h" 6 #include <iostream> 7 8 using namespace std; 9 10 void script_fun() 11 { 12 Py_Initialize(); /* Python解释器初始化 */ 13 PyRun_SimpleString("print \"hi,python!\""); /* 运行python字符串 */ 14 Py_Finalize(); /* 结束Python解释器,释放资源 */ 15 } 16 17 void HelloWorld(); 18 void Add(); 19 void TestTransferDict(); 20 void TestClass(); 21 22 int _tmain(int argc, _TCHAR* argv[]) 23 { 24 //直接运行python的执行语句 25 script_fun(); 26 //C_python_fun(); 27 cout << "Starting Test..." << endl; 28 cout << "HelloWorld()-------------" << endl; 29 HelloWorld(); 30 cout << "Add()--------------------" << endl; 31 Add(); 32 cout << "TestDict-----------------" << endl; 33 TestTransferDict(); 34 cout << "TestClass----------------" << endl; 35 TestClass(); 36 system("pause"); 37 return 0; 38 } 39 40 //调用输出"Hello World"函数 41 void HelloWorld() 42 { 43 Py_Initialize(); //使用python之前,要调用Py_Initialize();这个函数进行初始化 44 PyObject * pModule = NULL; //声明变量 45 PyObject * pFunc = NULL; //声明变量 46 pModule = PyImport_ImportModule("pytest"); //这里是要调用的Python文件名 47 pFunc = PyObject_GetAttrString(pModule, "HelloWorld"); //这里是要调用的函数名 48 PyEval_CallObject(pFunc, NULL); //调用函数,NULL表示参数为空 49 Py_Finalize(); //调用Py_Finalize,这个和Py_Initialize相对应的. 50 } 51 52 //调用Add函数,传两个int型参数 53 void Add() 54 { 55 Py_Initialize(); 56 PyObject * pModule = NULL; 57 PyObject * pFunc = NULL; 58 pModule = PyImport_ImportModule("pytest"); //pytest:Python文件名 59 pFunc = PyObject_GetAttrString(pModule, "add"); //Add:Python文件中的函数名 60 //创建参数: 61 PyObject *pArgs = PyTuple_New(2); //函数调用的参数传递均是以元组的形式打包的,2表示参数个数 62 PyTuple_SetItem(pArgs, 0, Py_BuildValue("i", 5));//0---序号 i表示创建int型变量 63 PyTuple_SetItem(pArgs, 1, Py_BuildValue("i", 7));//1---序号 64 //返回值 65 PyObject *pReturn = NULL; 66 pReturn = PyEval_CallObject(pFunc, pArgs); //调用函数 67 //将返回值转换为int类型 68 int result; 69 PyArg_Parse(pReturn, "i", &result); //i表示转换成int型变量 70 cout << "5+7 = " << result << endl; 71 Py_Finalize(); 72 } 73 74 //参数传递的类型为字典 75 void TestTransferDict() 76 { 77 Py_Initialize(); 78 PyObject * pModule = NULL; 79 PyObject * pFunc = NULL; 80 pModule = PyImport_ImportModule("pytest"); //pytest:Python文件名 81 pFunc = PyObject_GetAttrString(pModule, "TestDict"); //Add:Python文件中的函数名 82 //创建参数: 83 PyObject *pArgs = PyTuple_New(1); 84 PyObject *pDict = PyDict_New(); //创建字典类型变量 85 PyDict_SetItemString(pDict, "Name", Py_BuildValue("s", "WangYao")); //往字典类型变量中填充数据 86 PyDict_SetItemString(pDict, "Age", Py_BuildValue("i", 25)); //往字典类型变量中填充数据 87 PyTuple_SetItem(pArgs, 0, pDict);//0---序号 将字典类型变量添加到参数元组中 88 //返回值 89 PyObject *pReturn = NULL; 90 pReturn = PyEval_CallObject(pFunc, pArgs); //调用函数 91 //处理返回值: 92 int size = PyDict_Size(pReturn); 93 cout << "返回字典的大小为: " << size << endl; 94 PyObject *pNewAge = PyDict_GetItemString(pReturn, "Age"); 95 int newAge; 96 PyArg_Parse(pNewAge, "i", &newAge); 97 cout << "True Age: " << newAge << endl; 98 Py_Finalize(); 99 } 100 101 //测试类 102 void TestClass() 103 { 104 Py_Initialize(); 105 PyObject * pModule = NULL; 106 PyObject * pFunc = NULL; 107 pModule = PyImport_ImportModule("pytest"); //pytest:Python文件名 108 pFunc = PyObject_GetAttrString(pModule, "TestDict"); //Add:Python文件中的函数名 109 //获取Person类 110 PyObject *pClassPerson = PyObject_GetAttrString(pModule, "Person"); 111 //创建Person类的实例 112 PyObject *pInstancePerson = PyInstance_New(pClassPerson, NULL, NULL); 113 //调用方法 114 PyObject_CallMethod(pInstancePerson, "greet", "s", "Hello Kitty"); //s表示传递的是字符串,值为"Hello Kitty" 115 Py_Finalize(); 116 }
1 #!/usr/bin/python 2 # -*- coding: utf-8 -*- 3 4 def Hello(s): 5 print "Hello, world!" 6 print s 7 8 def HelloWorld(): 9 print "Hello World" 10 def add(a, b): 11 return a+b 12 def TestDict(dict): 13 print dict 14 dict["Age"] = 17 15 return dict 16 class Person: 17 def greet(self, greetStr): 18 print greetStr 19 #print add(5,7) 20 #a = raw_input("Enter To Continue...")
运行结果:
2、Python调用C++(使用python中的ctypes模块可以很方便的调用windows的dll(也包括linux下的so等文件))
1 from ctypes import * 2 dll = CDLL("add.dll") 3 print dll.Add(1, 102)
还有一种方式是利用boost库中的,boost.python方式,这种方式目前没有做过尝试,放在下一篇继续记录我的实践操作吧,感谢大家的支持!
本文来自博客园,作者:suntl,转载请注明原文链接:https://www.cnblogs.com/stlong/p/4771568.html