zoukankan      html  css  js  c++  java
  • 混合编程杂谈

      此文抛砖引玉,仅作记录,希望广大网友多多指正,谢谢!

      最近接触了混编的项目,项目是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混合编程操作的例子:

      一、环境搭建

    1. 安装python2.7(其他版本的python环境不影响下面的操作,只是注意区分不同的设置)
    2. 配置vs2013项目(python自带的python27.dllrelease版本,所以vs2013项目也必须调整为release,如果需要debug版本可以下载python源码自己编译,也可以在网上找找有没有好心人编译好的。
    3. 使用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 }
    C++代码调用python
     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方式,这种方式目前没有做过尝试,放在下一篇继续记录我的实践操作吧,感谢大家的支持!

  • 相关阅读:
    浅谈几种筛法
    [jzoj]4271. 【NOIP2015模拟10.27】魔法阵(37种转移的dp)
    【gdoi2018 day2】第二题 滑稽子图(subgraph)(性质DP+多项式)
    礼物(中国剩余定理+拓展gcd求逆元+分治=拓展Lucus)
    【GDOI2016模拟3.15】基因合成(回文串+性质+DP)
    【NOIP2013模拟】终极武器(经典分析+二分区间)
    【GDOI2016模拟3.16】幂(容斥 + 模型复杂转化)
    Hbase-cdh5.14.2与kylin集成异常
    拉链表
    数仓分层的理解
  • 原文地址:https://www.cnblogs.com/stlong/p/4771568.html
Copyright © 2011-2022 走看看