zoukankan      html  css  js  c++  java
  • C++ boost.python折腾笔记

    为了让当年研究生时写的图像处理系统重出江湖起到更大的作用,应研究生导师的意见,对原有的c++框架做了python扩展处理,为了避免遗忘,备注如下:

    一、boost 编译

    下载boost源码,这里使用boost 1.67,解压到目录,进行编译

    • 下载C++的boost库:
    • 安装Anaconda3-5.1.0-Windows-x86_64 默认路径安装
    • 解压boost文件,在其目录中执行.ootstrap.bat,会生成编译器b2.exebjam.exe
    • 修改project-config.jam文件,加入python的版本及路径(不加入则会默认python2):
    • import option ; 
    • using msvc ;

      option.set keep-going : false ;

      using python
      : 3.6 # Version
      : C:\ProgramData\Anaconda3\python.exe # Python Path
      : C:\ProgramData\Anaconda3\include # include path
      : C:\ProgramData\Anaconda3\libs # lib path(s)
      ;

    • 执行命令(我这里是vs 2010 故为msvc-10.0)`.jam.exe toolset=msvc-10.0 --with-python threading=multi link=shared address-model=64,在 stagelib 目录中会生成 boost_numpy3-*boost_python3-* 字样的文件
    • 编译过程遇到了以下问题
    • (1)缺少头文件 无法打开包括文件:“inttypes.h
    • #include<inttypes.h>

      编译时,找不到此文件,所以无法打开

      方法:

      1. 获取此文件

      2. 放置此文件到目录:

      VS2008,C:Program FilesMicrosoft Visual Studio 9.0VCinclude
      VS2010,C:Program FilesMicrosoft Visual Studio 10.0VCinclude

    • (2)boost 1.67的bug   找不到库
    • C:Boostincludeoost-1_67oostpython umpyconfig.hpp
    • 修改这一段
    • // enable automatic library variant selection ------------------------------//

      #if !defined(BOOST_NUMPY_SOURCE) && !defined(BOOST_ALL_NO_LIB) && !defined(BOOST_NUMPY_NO_LIB)
      //
      // Set the name of our library, this will get undef'ed by auto_link.hpp
      // once it's done with it:
      //
      //#define BOOST_LIB_NAME boost_numpy##PY_MAJOR_VERSION##PY_MINOR_VERSION
      #define _BOOST_PYTHON_CONCAT(N, M, m) N ## M ## m
      #define BOOST_PYTHON_CONCAT(N, M, m) _BOOST_PYTHON_CONCAT(N, M, m)
      #define BOOST_LIB_NAME BOOST_PYTHON_CONCAT(boost_numpy, PY_MAJOR_VERSION, PY_MINOR_VERSION)
      //
      // If we're importing code from a dll, then tell auto_link.hpp about it:
      //
      #ifdef BOOST_NUMPY_DYNAMIC_LIB
      # define BOOST_DYN_LINK
      #endif
      //
      // And include the header that does the work:
      //
      #include <boost/config/auto_link.hpp>
      #endif // auto-linking disabled

      #undef BOOST_PYTHON_CONCAT
      #undef _BOOST_PYTHON_CONCAT

      #define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION

      #endif // CONFIG_NUMPY20170215_H_

     文件C:Boostincludeoost-1_67oostpythondetailconfig.hpp

    #define _BOOST_PYTHON_CONCAT(N, M, m) N ## M ## m
    #define BOOST_PYTHON_CONCAT(N, M, m) _BOOST_PYTHON_CONCAT(N, M, m)
    #define BOOST_LIB_NAME BOOST_PYTHON_CONCAT(boost_python, PY_MAJOR_VERSION, PY_MINOR_VERSION)
    //
    // If we're importing code from a dll, then tell auto_link.hpp about it:
    //
    #ifdef BOOST_PYTHON_DYNAMIC_LIB
    # define BOOST_DYN_LINK
    #endif
    //
    // And include the header that does the work:
    //
    #include <boost/config/auto_link.hpp>
    #endif // auto-linking disabled

    #undef BOOST_PYTHON_CONCAT
    #undef _BOOST_PYTHON_CONCAT

    #ifndef BOOST_PYTHON_NO_PY_SIGNATURES
    #define BOOST_PYTHON_SUPPORTS_PY_SIGNATURES // enables smooth transition
    #endif

    #if !defined(BOOST_ATTRIBUTE_UNUSED) && defined(__GNUC__) && (__GNUC__ >= 4)
    # define BOOST_ATTRIBUTE_UNUSED __attribute__((unused))
    #endif

    二、在VS2010中引用

    ProjectProject PropertyConfiguration PropertiesVC++ Directories 中,Library Directories 中需要包含C:Boostlib;C:ProgramDataAnaconda3libs;$(LibraryPath);Include Directories 中需要包含C:Boostincludeoost-1_67;C:ProgramDataAnaconda3include;$(IncludePath)

    另外要选择MD多线程。

    三、在C++中如何调用python3的脚本

    样例代码如下:

    class ECT_PROCESSOR
    {
    public:
        ECT_PROCESSOR()
        {
    		Param1="";
    		Param2="";
    		Param3="";
    		Param4="";
    		Param5="";
    		Param6="";
    		Param7="";
    		Param8="";
    		Param9="";
    		Param10="";
    		dimx=0;
    		dimy=0;
    		dimz=0;
    
    	}
    	~ECT_PROCESSOR()
        {
    		
    	}
    	void SetModel(Model * in_p_model)
        {
    		p_model=in_p_model;
    	}
    
        bool SetSrcValue(int x, int y,int z,int tag, short val)
        {
    		
        }
    	short GetSrcValue(int x, int y,int z,int tag)
        {
    		
        }
    
    	bool SetMaskValue(int x, int y,int z, unsigned char val)
        {
    		
        }
    	unsigned char GetMaskValue(int x, int y,int z)
        {
    		
    		
        }
    	std::string Param1;
    	std::string Param2;
    	std::string Param3;
    	std::string Param4;
    	std::string Param5;
    	std::string Param6;
    	std::string Param7;
    	std::string Param8;
    	std::string Param9;
    	std::string Param10;
    	int dimx;
    	int dimy;
    	int dimz;
    
    private:
        Model *p_model;
    };
    
    
    ECT_PROCESSOR* GetECT_PROCESSORInstance()
    {
        static ECT_PROCESSOR* the_ECT_PROCESSOR = NULL;
        if (!the_ECT_PROCESSOR)
        {
    		the_ECT_PROCESSOR = new ECT_PROCESSOR();
    		the_ECT_PROCESSOR->SetModel(Model::GetModelInstance());
        }
        return the_ECT_PROCESSOR;
    }
    
    // export c++ function and class to python
    BOOST_PYTHON_MODULE(MyEngine)
    {
        using namespace boost::python;
        def("GetECT_PROCESSORInstance", GetECT_PROCESSORInstance,
    		return_value_policy< reference_existing_object >());
        class_<ECT_PROCESSOR>("ECT_PROCESSOR", "ECT_PROCESSOR")
          .def("SetSrcValue", &ECT_PROCESSOR::SetSrcValue,
          args("x", "y","z","tag""val"))
    	  .def("GetSrcValue", &ECT_PROCESSOR::GetSrcValue,
          args("x","y","z","tag"))
    	  .def("SetMaskValue", &ECT_PROCESSOR::SetMaskValue,
          args("x","y","z","val"))
    	  .def("GetMaskValue", &ECT_PROCESSOR::GetMaskValue,
          args("x", "y","z"))
    	  .def_readonly("Param1", &ECT_PROCESSOR::Param1,"Param1")
    	  .def_readonly("Param2", &ECT_PROCESSOR::Param2,"Param2")
    	  .def_readonly("Param3", &ECT_PROCESSOR::Param3,"Param3")
    	  .def_readonly("Param4", &ECT_PROCESSOR::Param4,"Param4")
    	  .def_readonly("Param5", &ECT_PROCESSOR::Param5,"Param5")
    	  .def_readonly("Param6", &ECT_PROCESSOR::Param6,"Param6")
    	  .def_readonly("Param7", &ECT_PROCESSOR::Param7,"Param7")
    	  .def_readonly("Param8", &ECT_PROCESSOR::Param8,"Param8")
    	  .def_readonly("Param9", &ECT_PROCESSOR::Param9,"Param9")
    	  .def_readonly("Param10", &ECT_PROCESSOR::Param10,"Param10")
    	  .def_readonly("dimx", &ECT_PROCESSOR::dimx,"dimx")
    	  .def_readonly("dimy", &ECT_PROCESSOR::dimy,"dimy")
    	  .def_readonly("dimz", &ECT_PROCESSOR::dimz,"dimz")
    	  ;
    }
    bool InitPython()
    {
        Py_Initialize();
    
        if(!Py_IsInitialized())
        {
    		return false;
        }
    	return true;
    }
     int Controller::ExcutePythonScript_ECT(CString sInFilePath,CString sInFileName,CString sInParam1,CString sInParam2,CString sInParam3,CString sInParam4,CString sInParam5,
    	 CString sInParam6,CString sInParam7,CString sInParam8,CString sInParam9,CString sInParam10,CString *pOutMsg)
     {
    	int tmp_ectindex=model->GetActiveEctIndex();
    	if(tmp_ectindex<0)
    	{
    		//报错
    		OutputLogB("Log.log", __FILE__, __LINE__, "model->GetActiveEctIndex<0");
    		return -1;
    	}
    	try
        {
    		CString sModuleName;
    		std::string stdModuleName;
    		std::string stdModulePath(sInFilePath.GetBuffer());
    		int pos = sInFileName.ReverseFind('.');
    		if ( pos > 0 )
    		{
    			sModuleName = sInFileName.Left(pos);
    			stdModuleName=sModuleName.GetBuffer(0);
    		}
    		else
    		{
    			stdModuleName=sInFileName.GetBuffer(0);
    		}
    		
    		std::ifstream fin;  
    		char sFullPath[256]={0};
    		snprintf(sFullPath,sizeof(sFullPath),"%s\%s",stdModulePath.c_str(),sInFileName.GetBuffer());
    		OutputLogB("Log.log", __FILE__, __LINE__, "fin.open(%s)",sFullPath);
    		fin.open(sFullPath);  
    		std::string str;  
    		std::string str_in = "";  
    		while (getline(fin, str))    //一行一行地读到字符串str_in中  
    		{  
    			str_in = str_in + str + '
    ';  
    		 }  
    		 fin.close();  
    		 
    
    		using namespace boost::python;
    
    		  if (PyImport_AppendInittab(const_cast<char*>("MyEngine"),
    			#if PY_VERSION_HEX >= 0x03000000 
                                 PyInit_MyEngine 
    			#else 
                                 initMyEngine 
    			#endif 
                                 ) == -1)
    			{
    				OutputLogB("Log.log", __FILE__, __LINE__,"Failed to add embedded_hello to the interpreter's builtin modules");
    				return -2;
    			}
    
    		//PyImport_AppendInittab( stdModuleName.c_str(), &PyInit_MyEngine );
    		if(!InitPython())
    		{
    			return -1;
    		 }
    		PyInit_MyEngine(); // init MyEngine Module
    
      // Add current path to sys.path. You have to
      // do this in linux. While in Windows,
      // current path is already in sys.path.
    
    		ECT_PROCESSOR* pECT_PROCESSOR = GetECT_PROCESSORInstance();
    		pECT_PROCESSOR->Param1=sInParam1.GetBuffer();
    		pECT_PROCESSOR->Param2=sInParam2.GetBuffer();
    		pECT_PROCESSOR->Param3=sInParam3.GetBuffer();
    		pECT_PROCESSOR->Param4=sInParam4.GetBuffer();
    		pECT_PROCESSOR->Param5=sInParam5.GetBuffer();
    		pECT_PROCESSOR->Param6=sInParam6.GetBuffer();
    		pECT_PROCESSOR->Param7=sInParam7.GetBuffer();
    		pECT_PROCESSOR->Param8=sInParam8.GetBuffer();
    		pECT_PROCESSOR->Param9=sInParam9.GetBuffer();
    		pECT_PROCESSOR->Param10=sInParam10.GetBuffer();
    
    		object main_module = import( "__main__" );
    		object main_namespace = main_module.attr( "__dict__" );
    
    		object ignored = exec(
    		 "import sys
    "
    		"sys.path.append('.')
    ", main_namespace );
    
    	
    		int dimxyz[3]={0};
    		model->GetActiveMask()->GetDimensions(dimxyz);
    		pECT_PROCESSOR->dimx=dimxyz[0];
    		pECT_PROCESSOR->dimy=dimxyz[0];
    		pECT_PROCESSOR->dimz=dimxyz[0];
    		
    		object ignored2 = exec(str_in.c_str(),
                              main_namespace);
    
    		return 0;
    
        }
    	catch (boost::python::error_already_set const &)
        {
            std::string perror_str = parse_python_exception();
    		pOutMsg->SetString(perror_str.c_str());
    		PyErr_Print();
            PyErr_Clear();
            //delete _module;
            //_module = NULL;
           // Py_Finalize();
    		return -2;
        }
    
     }
    

      

  • 相关阅读:
    使用 star UML制作的图
    评价片段
    项目部分
    用新学的知识 写了一段小代码
    常用系统存储过程
    考试小总结
    分页
    行转列面试题 事例
    子查询
    生成验证码的方法集合(一)
  • 原文地址:https://www.cnblogs.com/qwcbeyond/p/9085327.html
Copyright © 2011-2022 走看看