posts - 85,  comments - 69,  views - 13万

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

一、boost 编译

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

  • 下载C++的boost库:
  • 安装Anaconda3-5.1.0-Windows-x86_64 默认路径安装
  • 解压boost文件,在其目录中执行.\bootstrap.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)`.\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中引用

ProjectProject PropertyConfiguration PropertiesVC++ 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;
    }
 
 }

  

 

 

posted on   30斤大番薯  阅读(679)  评论(0编辑  收藏  举报
< 2025年3月 >
23 24 25 26 27 28 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 1 2 3 4 5

点击右上角即可分享
微信分享提示