为了让当年研究生时写的图像处理系统重出江湖起到更大的作用,应研究生导师的意见,对原有的c++框架做了python扩展处理,为了避免遗忘,备注如下:
一、boost 编译
下载boost源码,这里使用boost 1.67,解压到目录,进行编译
- 下载C++的boost库:http://www.boost.org/
- 安装Anaconda3-5.1.0-Windows-x86_64 默认路径安装
- 解压boost文件,在其目录中执行
.\bootstrap.bat
,会生成编译器b2.exe
和bjam.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)
`.\bjam.exe toolset=msvc-10.0 --with-python threading=multi link=shared address-model=64
,在stage\lib
目录中会生成boost_numpy3-*
和boost_python3-*
字样的文件 - 编译过程遇到了以下问题
- (1)缺少头文件 无法打开包括文件:“inttypes.h
-
#include<inttypes.h>
编译时,找不到此文件,所以无法打开
方法:
1. 获取此文件
2. 放置此文件到目录:
VS2008,C:\Program Files\Microsoft Visual Studio 9.0\VC\include
VS2010,C:\Program Files\Microsoft Visual Studio 10.0\VC\include - (2)boost 1.67的bug 找不到库
- C:\Boost\include\boost-1_67\boost\python\numpy\config.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:\Boost\include\boost-1_67\boost\python\detail\config.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中引用
在 Project
→Project Property
→Configuration Properties
→VC++ Directories
中,Library Directories
中需要包含C:\Boost\lib;C:\ProgramData\Anaconda3\libs;$(LibraryPath);Include Directories
中需要包含C:\Boost\include\boost-1_67;C:\ProgramData\Anaconda3\include;$(IncludePath)
另外要选择MD多线程。
三、在C++中如何调用python3的脚本
样例代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 | 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 + '\n' ; } 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\n" "sys.path.append('.')\n" , 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; } } |
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步