Boost.Python使用小结

<p id="zw-126cd2e908cnbA5du9788">来源:<a href="http://blog.csdn.net/KongDong">http://blog.csdn.net/KongDong</a>

</p>
<p>作者:fasiondog</p>
<p></p>
<p>万事开头难!前段日子因为性能问题升级了机器,程序语言也从python转到了C++,不过因为数据分析的问题,还是交互式的环境用着方便,于是埋头又将编好的C++库切回python,不过这一回用的是Boost.Python,刚开始编译总是有问题,查看文档才发现Boost.Python中的构建说明帮助不够完全,如果没仔细学习Boost.Build的话,要按自己的方式编译的话还是很麻烦。费劲力气之后,终于把程序库的编译架子搭起来,之后就势如破竹了,现在使用Boost.Python真的很畅快。一辆没钥匙的新车,开不起来是多么恼火的事情啊!如果希望使用Boost.Python,而卡在起点不能前进,那滋味真不好受:( </p>
<p></p>
<p>下面简单总结一下使用Boost.Python建立自己的编译工程的方法,便于快速进入Boost.Python。其实,建立自己的编译工程主要的问题就是Boost.Build涉及的多个配置文件,而在Boost.Python的构建说明文档中说的不全面,导致总是被卡。<span style="color: #ff0000;">下面的红色字体部分是我的注释说明。</span>

</p>
<p>(注:我的编译环境是linux + gcc)</p>
<p></p>
<p>
   1、在用户根目录下建立user-config.jam文件,如下:
</p>
<p id="zw-126cd2e908cnbA5du9788"></p>
<table id="zw-126cd327ee4jUg7P_9788" style="border-style: dotted; width: 100%; background-image: none; text-align: left; vertical-align: top;" border="1" cellspacing="0" cellpadding="6" frame="box" rules="all"><tbody id="zw-126cd327ee5s8S-DV9788"><tr id="zw-126cd327ee5rgz3sN9788" style="vertical-align: middle;">
<td id="zw-126cd327ee5xNK6qQ9788" style="width: 100%; background-color: #c0c0c0; background-image: none; text-align: left; vertical-align: top;">
<p id="zw-126cd337905Dt2v6O9788" style="line-height: 1.2;">
               # MSVC configuration
               <br id="zw-126cd337905r7rGQ09788">

               using gcc ;
               <br id="zw-126cd3379058xaxck9788"><br id="zw-126cd337905M4AmQC9788">

               # Python configuration
               <br id="zw-126cd33790599YTyf9788">

               using python : 2.6 : /usr ;
            </p>
<p id="zw-126cd3343beK6nmk-9788"></p>
</td>
</tr></tbody></table>
<p></p>
<p id="zw-126cd351a16QWkrxt9788">
   2、在CPP文件工作目录下,建立boost-build.jam,如下:
</p>
<p id="zw-126cd38d168yUsuO9788"></p>
<table id="zw-126cd377548SJ_t89788" style="width: 1112px; height: 38px;" border="1" cellpadding="7" frame="box" rules="all"><tbody id="zw-126cd377548SRWZKz9788"><tr id="zw-126cd377548ZOuBQb9788" style="vertical-align: middle;">
<td id="zw-126cd377549tOWwBE9788" style="width: 100%; background-color: #c0c0c0; background-image: none; text-align: left; vertical-align: top;">
<p id="zw-126cd37754960bDFo9788">
               <span id="zw-126cd388c4cCYU1iT9788">
                  # Copyright David Abrahams 2006. Distributed under the Boost
               </span>

               <br id="zw-126cd388c49WKblYs9788"><span id="zw-126cd388c4cBnDmNp9788">
                  # Software License, Version 1.0. (See accompanying
               </span>

               <br id="zw-126cd388c4auREnR9788"><span id="zw-126cd388c4dBGsq09788">
                  # file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
               </span>

               <br id="zw-126cd388c4aB5WKf29788"><br id="zw-126cd388c4auJCr9788"><span id="zw-126cd388c4dV5CtJz9788">
                  # Edit this path to point at the tools/build/v2 subdirectory of your
               </span>

               <br id="zw-126cd388c4aGIHRlu9788"><span id="zw-126cd388c4du8izWI9788">
                  # Boost installation. Absolute paths work, too.
               </span>

               <br id="zw-126cd388c4aPMFvTG9788"><span id="zw-126cd388c4egW6ebR9788">
                  boost-build /home/fasiondog/src/boost_1_42_0/tools/build/v2 ; <span style="color: #ff0000;"> #指明Boost库构建的位置,需自行修改</span>

</span>

            </p>
</td>
</tr></tbody></table>
<p id="zw-126cd351a16QWkrxt9788">
   <br id="zw-126cd38c952ZKK3cR9788"></p>
<p id="zw-126cd351a16QWkrxt9788">
   3、在CPP文件工作目录下,建立Jamroot文件,如下:
</p>
<p id="zw-126cd38d168H2bwrL9788"></p>
<table id="zw-126cd38dd0d-GMsgv9788" style="width: 100%;" border="1" cellpadding="7" frame="box" rules="all"><tbody id="zw-126cd38dd0dsn8LXn9788"><tr id="zw-126cd38dd0dlWXr9788" style="vertical-align: middle;">
<td id="zw-126cd38dd0dRVmhp79788" style="width: 100%; background-color: #c0c0c0; background-image: none; text-align: left; vertical-align: top;">
<p id="zw-126cd38dd0dLcMl2-9788"><span style="color: #ff0000;">#这是Boost.Python的示例,需要修改哪些地方,请往后一例子</span>

</p>
<p><span id="zw-126cd3954dcW44Q039788"># Copyright David Abrahams 2006. Distributed under the Boost
               </span>

               <br id="zw-126cd3954d5hMrlEz9788"><span id="zw-126cd3954ddv479F59788">
                  # Software License, Version 1.0. (See accompanying
               </span>

               <br id="zw-126cd3954d5UFkCTt9788"><span id="zw-126cd3954ddgcDdrv9788">
                  # file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
               </span>

               <br id="zw-126cd3954d5B88WKe9788"><br id="zw-126cd3954d5CCnJcu9788"><span id="zw-126cd3954ddGAvZJw9788">
                  import python ;
               </span>

               <br id="zw-126cd3954d52Na9S-9788"><br id="zw-126cd3954d5_7fwt79788"><span id="zw-126cd3954deijzONd9788">
                  if ! [ python.configured ]
               </span>

               <br id="zw-126cd3954d5dbboPE9788"><span id="zw-126cd3954de2I22q19788">
                  {
               </span>

               <br id="zw-126cd3954d6wcqP19788"><span id="zw-126cd3954deDhRvKv9788">
                   ECHO "notice: no Python configured in user-config.jam" ;
               </span>

               <br id="zw-126cd3954d6U_UG0l9788"><span id="zw-126cd3954df-n-gG59788">
                   ECHO "notice: will use default configuration" ;
               </span>

               <br id="zw-126cd3954d6zKFx-_9788"><span id="zw-126cd3954dfwxXbtE9788">
                   using python ;
               </span>

               <br id="zw-126cd3954d6UKT4zY9788"><span id="zw-126cd3954dfr4TH2R9788">
                  }
               </span>

               <br id="zw-126cd3954d6Q6jc-Y9788"><br id="zw-126cd3954d6KsZ239788"><span id="zw-126cd3954e09EQJFD9788">
                  # Specify the path to the Boost project. If you move this project,
               </span>

               <br id="zw-126cd3954d6T8dp8D9788"><span id="zw-126cd3954e0AlAjRf9788">
                  # adjust this path to refer to the Boost root directory.
               </span>

               <br id="zw-126cd3954d6wTrvs79788"><span id="zw-126cd3954e16_pu9788">
                  use-project boost
               </span>

               <br id="zw-126cd3954d6u3ubx9788"><span id="zw-126cd3954e1E-eSz9788">
                   : /home/fasiondog/src/boost_1_42_0 ;
               </span>

               <br id="zw-126cd3954d6QItmf9788"><br id="zw-126cd3954d717PGuv9788"><span id="zw-126cd3954e1bT9VT09788">
                  # Set up the project-wide requirements that everything uses the
               </span>

               <br id="zw-126cd3954d7_xJDtC9788"><span id="zw-126cd3954e2n6jnc9788">
                  # boost_python library from the project whose global ID is
               </span>

               <br id="zw-126cd3954d7N7DZL79788"><span id="zw-126cd3954e2YzYiTO9788">
                  # /boost/python.
               </span>

               <br id="zw-126cd3954d7W71FcB9788"><span id="zw-126cd3954e2lmqNYS9788">
                  project
               </span>

               <br id="zw-126cd3954d7rO96n9788"><span id="zw-126cd3954e3kg2YQL9788">
                   : requirements &lt;library&gt;/boost/python//boost_python ;
               </span>

               <br id="zw-126cd3954d7yihcyZ9788"><br id="zw-126cd3954d7fUU7_69788"><span id="zw-126cd3954e3hIhhP9788">
                  # Declare the three extension modules. You can specify multiple
               </span>

               <br id="zw-126cd3954d7LwutKz9788"><span id="zw-126cd3954e4gn6lBj9788">
                  # source files after the colon separated by spaces.
               </span>

               <br id="zw-126cd3954d76b63ua9788"><span id="zw-126cd3954e4mtWQ9788">
                  python-extension hello_ext : hello.cpp ;
               </span>

               <br id="zw-126cd3954d7dpYeFl9788"><br id="zw-126cd3954d7tHEtyt9788"><span id="zw-126cd3954e4RiU7iz9788">
                  # A little "rule" (function) to clean up the syntax of declaring tests
               </span>

               <br id="zw-126cd3954d8uZXEM29788"><span id="zw-126cd3954e518gPh9788">
                  # of these extension modules.
               </span>

               <br id="zw-126cd3954d8RlmW0I9788"><span id="zw-126cd3954e5tumIt9788">
                  local rule run-test ( test-name : sources + )
               </span>

               <br id="zw-126cd3954d8sMRcbr9788"><span id="zw-126cd3954e5gM4qf9788">
                  {
               </span>

               <br id="zw-126cd3954d8cVpqf_9788"><span id="zw-126cd3954e6QRhmVK9788">
                   import testing ;
               </span>

               <br id="zw-126cd3954d8P6flO49788"><span id="zw-126cd3954e68EpqWQ9788">
                   testing.make-test run-pyd : $(sources) : : $(test-name) ;
               </span>

               <br id="zw-126cd3954d8zfJjyk9788"><span id="zw-126cd3954e6t73EBi9788">
                  }
               </span>

               <br id="zw-126cd3954d8LiB4Yz9788"><br id="zw-126cd3954d8Vhv-UU9788"><span id="zw-126cd3954e7OniKaM9788">
                  # Declare test targets
               </span>

               <br id="zw-126cd3954d8XVEkL19788"><span id="zw-126cd3954e7YZsX49788">
                  run-test hello : hello_ext hello.py ;
               </span>

            </p>
</td>
</tr></tbody></table>
<p id="zw-126cd38dd10_Z4zYN9788">
   <br id="zw-126e17c8309h7_59788"></p>
<p id="zw-126e17c830943bTnF9788">
   自己用的一个Jamroot实例:
</p>
<p id="zw-126e17c830943bTnF9788"></p>
<table id="zw-126e17cf8adj5zjpa9788" style="width: 1112px; height: 38px;" border="1" cellpadding="7" frame="box" rules="all"><tbody id="zw-126e17cf8aeb9JZN59788"><tr id="zw-126e17cf8aeNo_FwE9788" style="vertical-align: middle;">
<td id="zw-126e17cf8aesdLyER9788" style="width: 100%; background-color: #c0c0c0; background-image: none; text-align: left; vertical-align: top;">
<p id="zw-126e17cf8aeBFMpsk9788"></p>
<p id="zw-126e17eb27fKfj2z19788">
               # Copyright David Abrahams 2006. Distributed under the Boost
               <br id="zw-126e17eb27fwNxobT9788">

               # Software License, Version 1.0. (See accompanying
               <br id="zw-126e17eb27fNBiBls9788">

               # file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
               <br id="zw-126e17eb27fitj4RI9788"><br id="zw-126e17eb27f0C-dHH9788">

               import python ;
               <br id="zw-126e17eb280sHD9Cx9788"><br id="zw-126e17eb280S3ZAz9788">

               if ! [ python.configured ]
               <br id="zw-126e17eb280_YoAnv9788">

               {
               <br id="zw-126e17eb280StFWvR9788">

                ECHO "notice: no Python configured in user-config.jam" ;
               <br id="zw-126e17eb280Mtn4x99788">

                ECHO "notice: will use default configuration" ;
               <br id="zw-126e17eb280e5nTN09788">

                using python ;
               <br id="zw-126e17eb2809j-xz9788">

               }
               <br id="zw-126e17eb2809pdsUO9788"><br id="zw-126e17eb280NDypLq9788">

               # Specify the path to the Boost project. If you move this project,
               <br id="zw-126e17eb281ecwG1r9788">

               # adjust this path to refer to the Boost root directory.
               <br id="zw-126e17eb281V9fJdY9788">

               use-project boost
               <br id="zw-126e17eb2819VDjw39788">

                : /home/fasiondog/src/boost_1_42_0 ;
               <br id="zw-126e17eb281laOG8Q9788"><br id="zw-126e17eb281Arnqqc9788">

               # Set up the project-wide requirements that everything uses the
               <br id="zw-126e17eb281rqdD0t9788">

               # boost_python library from the project whose global ID is
               <br id="zw-126e17eb2818_eRx9788">

               # /boost/python.
               <br id="zw-126e17eb281iA5bpB9788">

               project
               <br id="zw-126e17eb2815Jvy89788">

                : requirements &lt;library&gt;/boost/python//boost_python
               <br id="zw-126e17eb28252n0j99788">

                ;
               <br id="zw-126e17eb282Ndtqi9788"></p>
<p></p>
<p><span style="color: #ff0000;">#注意下面这一段,指明工程依赖的库/头文件/编译器的编译选项等等</span>

</p>
<p>
               project : requirements &lt;library&gt;/usr/lib/libgalaxy.so ; <span style="color: #ff0000;">#指明依赖的外部共享库</span>

<br id="zw-126e17eb282UDEXJY9788">

               project : requirements &lt;include&gt;/home/fasiondog/workspace/galaxy ;
               <span style="color: #ff0000;">#指明依赖的外部库头文件</span>

<br id="zw-126e17eb282WNtRTe9788">

               project : requirements &lt;cxxflags&gt;-std=c++0x ;
               <span style="color: #ff0000;">#编译器编译选项</span>

<br id="zw-126e17eb282-YaVvJ9788">

               #project : requirements &lt;cxxflags&gt;-fno-inline ;
               <span style="color: #ff0000;">#编译器编译选项</span>

<br id="zw-126e17eb282l5xnWF9788"><br id="zw-126e17eb282s7YHAd9788">

               # Declare the three extension modules. You can specify multiple
               <br id="zw-126e17eb283xGm76t9788">

               # source files after the colon separated by spaces.
               </p>
<p><span style="color: #ff0000;">#指明编译的目标输出,可以指明多个目标,下面要求输出两个目标: _cstock 和 _indicator.so,注意可以使用目录方式输出</span>

<br id="zw-126e17eb283VDBaZy9788">

               python-extension _cstock : main.cpp
               <br id="zw-126e17eb283qPn5GK9788">

                _DataType.cpp
               <br id="zw-126e17eb283jXuTN9788">

                _DataRecord.cpp
               <br id="zw-126e17eb283Y2WsS9788">

                _DataQuery.cpp
               <br id="zw-126e17eb283PdiDXy9788">

                _KData.cpp
               <br id="zw-126e17eb283G5wouq9788">

                _Stock.cpp
               <br id="zw-126e17eb283weZ6cD9788">

                _StockManager.cpp ;
            </p>
<p id="zw-126e17eb27fKfj2z19788">
               <br id="zw-126f5deda57_Ae26y9788"><span id="zw-126f5ded21cRRH0aR9788">
                  python-extension indicator/_indicator : indicator/_Indicator.cpp
               </span>

               <br id="zw-126f5ded21bYa67nn9788"><span id="zw-126f5ded21ddAFc-z9788">
                   indicator/_Indicator_main.cpp
               </span>

               <span id="zw-126f5ded21dlSSBhq9788">
                  ;
               </span>

               <br id="zw-126f5deb233h-IFff9788"><br id="zw-126f5deb233A3pG7W9788">

               # A little "rule" (function) to clean up the syntax of declaring tests
               <br id="zw-126f5deb233By8l7A9788">

               # of these extension modules.
               <br id="zw-126f5deb233I9XL9U9788">

               #local rule run-test ( test-name : sources + )
               <br id="zw-126f5deb2331j1iDf9788">

               #{
               <br id="zw-126f5deb233nEqT939788">

               # import testing ;
               <br id="zw-126f5deb234-UKvrm9788">

               # testing.make-test run-pyd : $(sources) : : $(test-name) ;
               <br id="zw-126f5deb234Ixt989788">

               #}
               <br id="zw-126f5deb2348SsGTU9788"><br id="zw-126f5deb234gtGZRs9788">

               # Declare test targets
               <br id="zw-126f5deb234iD4dW9788">

               #run-test hello : hello_ext hello.py ;
            </p>
<p id="zw-126f5ded221OSvUSJ9788"></p>
<p id="zw-126e17e2ce7robfSh9788"></p>
</td>
</tr></tbody></table>
<p id="zw-126e17cf8b2i6YOQ9788"></p>
<p id="zw-126cd351a16QWkrxt9788">
   4、在CPP文件工作目录下,直接运行bjam,默认编译成Debug版本,运行bjam release生成Release版本
</p>
<hr id="zw-126d727f83398y1EA9788" style="width: 100%; height: 2px;">
<p id="zw-126d72793e6Iitmnc9788"></p>
<p>下面是使用Eclipse编译的方法,供参考,优点是编译时按快捷键立即执行编译检查错误,缺点是编译多目标时不方便</p>
<p></p>
<p id="zw-126d727953f9BChoP9788">
   不使用Boost.Build工具的编译方法,在Eclipse中编译:(注:bjam可以同时编译多个目标,Eclipse做同样的事得建多个工程,目录结构会不清晰,并不比bjam方便,但编写代码时可以直接按快捷键进行编译快速检查错误,我的方法是在Eclipse中建一个工程,Jamroot里指定多目标,用Eclipse进行编译检查,编译通过后,最后再运行bjam编译并拷贝目标至相应目录)
</p>
<p id="zw-126dba77127CIKDZt9788"></p>
<p><img src="http://farm5.static.flickr.com/4060/4386683733_0d6bcd12f7_o.png" alt="" width="800" height="565"></p>
<p id="zw-126dba77128OyzAIk9788"></p>
<p id="zw-126dba77128MgTHtH9788">
   <img src="http://farm5.static.flickr.com/4052/4386683725_e47263c791_o.png" alt="" width="800" height="565"><br id="zw-126dba77128Xje6sO9788"></p>
<p></p>
<p><img src="http://farm5.static.flickr.com/4047/4386683735_cfd4359f5a_o.png" alt="" width="800" height="565"></p>
<p></p>
<p><img src="http://farm5.static.flickr.com/4012/4386683737_1f1bccd053_o.png" alt="" width="800" height="565"></p>
<p></p>
<hr id="zw-126dba7822cdjtd9788" style="width: 100%; height: 2px;">
<p id="zw-126dba78950g8seBN9788"></p>
<p>其他一些Boost.Python使用问题:</p>
<p></p>
<p>
   def(str(self) 无法编译问题:
</p>
<p id="zw-126dbaa512c8WfQBs9788">
   必须改写成def(self_ns::str(self))
</p>
<p id="zw-126dbaa512cVEvqYN9788">
   或者使用下面的函数方式:
</p>
<p id="zw-126f5d1d56eCmWEWJ9788">
    .def("__str__", &amp;MultiBoolean::ToString)
</p>
<p id="zw-126dba773b7eRnzos9788">
   <br id="zw-126f5d21c60zpEqRj9788"></p>
<p id="zw-126f5d21c60dsn2qm9788">
   注册boost::shared_ptr:
   <br id="zw-126f5d21c604Mj3Pd9788"></p>
<p id="zw-126f5d20900pn6SrX9788">
   register_ptr_to_python&lt;boost::shared_ptr&lt;XXXX&gt; &gt;();
</p>
<p id="zw-126f5d25a91v6x5EM9788">
   <br id="zw-126f5d2f1afr3nj89788"></p>
<p id="zw-126f5d2f1aftDKMHP9788">
   引出迭代子:
   <br id="zw-126f5d2f1afd2zm-Q9788"></p>
<p id="zw-126f5d2e81efSCVOq9788">
   .def("__iter__", iterator&lt;StockManager&gt;())
</p>
<p id="zw-126f5dc9f18970wOw9788">
   这里的iterator仅要求类具有 iterator::begin 和 iterator::end 成员函数即可,不需要C++迭代子中一大堆定义,很方便
</p>
<p id="zw-126f5dc9f18Pr4KES9788">
   <br id="zw-126f5dc9f18LP07H9788"></p>
<p id="zw-126f5dc9f18k0lhPc9788">
   虚函数和默认参数在boost帮助中写的很清楚
</p>
<p id="zw-126f5dc9f18m5Vc3e9788">
   对于继承关系使用 class_&lt;AAAA, bases(AAAABase)&gt;("AAAA"); 即使AAAABase已经使用了wrapper包装也没关系
</p>
<p id="zw-126f5dc9f18wkF-Nl9788">
   <br id="zw-126f5dc9f18A1s49788"></p>
<p id="zw-126f5dc9f18IY4DSZ9788">
   Boost.Python已经解决了默认参数的问题,对于python中的命名参数,可以在python中使用函数直接包装一层即可,如下:
</p>
<p id="zw-126f5dc9f14Pr6Izh9788">
   def KData_iter(kdata):
   <br id="zw-126f5dc9f14u-jRFv9788">

    for i in range(len(kdata)):
   <br id="zw-126f5dc9f15GINaP-9788">

    yield kdata[i]
</p>
<p id="zw-126f5dcaa84e0zZp9788">
   KData.__getitem__ = KData_getitem
</p>
<p id="zw-126f5db0b27TAK4A9788">
   <br id="zw-126f5dcb923ySxJ7_9788"></p>
<p id="zw-126f5dcb922ZX9hrR9788">
   对于初始化函数的命名参数可以使用python继承包装,如下:
   <br id="zw-126f5dcb923zsr_YE9788"></p>
<p id="zw-126f5db0b1eEb_gfv9788">
   class Query(DataQuery):
   <br id="zw-126f5db0b1dQQvmQX9788">

    def __init__(self, start = 0, end = DataQuery.NoneType.NONE, queryType = DataQuery.QueryType.INDEX,
   <br id="zw-126f5db0b20VqB3y9788">

    dataType=DataQuery.DataType.DAY, recoverType = DataQuery.RecoverType.NO_RECOVER):
   <br id="zw-126f5db0b20pQoH8N9788">

    super(Query, self).__init__(start, end, queryType, dataType, recoverType)
</p>
<p id="zw-126f5d2e81efSCVOq9788">
   <br id="zw-126f5e3b6c3SW2m8m9788"></p>
<p id="zw-126f5d2e81efSCVOq9788">
   简单引出std::vector容器,让其具有和python list类似的功能(不含切片)(下面的DataRecordList = std::vector&lt;DataRecord&gt;):
</p>
<p id="zw-126f5e3dcffLecVpy9788">
    DataRecordList::const_reference (DataRecordList::*DataRecordList_at)(DataRecordList::size_type) const = &amp;DataRecordList::at;
   <br id="zw-126f5e3dcffSnrf8N9788">

    class_&lt;DataRecordList&gt;("RecordList")
   <br id="zw-126f5e3dcffcOth39788">

    .def("__iter__", iterator&lt;DataRecordList&gt;())
   <br id="zw-126f5e3dcffbOI5pQ9788">

    .def("__len__", &amp;DataRecordList::size)
   <br id="zw-126f5e3dd00xAdb7G9788">

    .def("__getitem__", DataRecordList_at, return_value_policy&lt;copy_const_reference&gt;())
   <br id="zw-126f5e3dd00eOwMBO9788">

    ;
</p>
<p id="zw-126fbcbaa4bG9cCms9788">
   <br id="zw-126fbcbab6a5SxXKX9788"></p>
<p id="zw-126fbcbab6aQ4QPQN9788">
   对如下C++用法, 在python中继承同名重载_func运行正常:
</p>
<p id="zw-126fbcc25f686xXIh9788">
   class Base{
</p>
<p id="zw-126fbcc84094NWXDB9788">
   public:
</p>
<p id="zw-126fbcc92c9jxGdT59788">
   int func_wrap() { return _func(); }
</p>
<p id="zw-126fbcd7b86NqaTh79788">
   protected:
</p>
<p id="zw-126fbcd9481LGBJE09788">
    virtual int _func() = 0;
   <br id="zw-126fbcd9481yUKLNy9788"></p>
<p id="zw-126fbcc43a8cJo5d9788">
   };
</p>
<p id="zw-126fbccf0aeuLGjvG9788">
   class T: public Base{
</p>
<p id="zw-126fbcdeaa0TpcpZA9788">
   private:
</p>
<p id="zw-126fbce1dd3P-6X2c9788">
    int _func(){ return 100; }
   <br id="zw-126fbce1dd3mBwzcj9788"></p>
<p id="zw-126fbcddccbt4xUYT9788">
   };
   <br id="zw-126fbcddccb502bo9788"></p>
<p id="zw-126fbccf66c3Zb-1j9788">
   在python中:
</p>
<p id="zw-126fbd029e5Hnds369788">
   class T(Base):
</p>
<p id="zw-126fbd029e6-bbO2J9788">
    def _func(self):
</p>
<p id="zw-126fbd05907Trdsa9788">
    return 100
   </p>
<p></p>
<p></p>
<p>===================================================</p>
<p>20100228 补充:</p>
<p>如何在Python中使用boost::any?</p>
<p>一个C++基类示例:</p>
<p>class TestBase{</p>
<p>public:</p>
<p> boost::any getParam(const std::string&amp; name, const boost::any&amp; value);</p>
<p> bool setParam(const std::string&amp; name, const boost::any&amp; value);</p>
<p> ……</p>
<p>};</p>
<p></p>
<p>通过普通的方式虽然可以引出getParam和setParam函数,但在python中却因boost::any存放类型不可知无法使用,可以按下面的方法解决,但是此时boost::any只能支持有限的类型。还有一种方法通过定义右值转换器,但是这种方法由于boost::any跨越共享库边界时,type_info(boost::any&lt;XX&gt;).name在不同的库中不一致,必须使用非安全转换,暂时不可取。</p>
<p></p>
<p></p>
<p>/*</p>
<p>* 定义boost::any To python转换,接近TestBase::getParam问题</p>
<p>*/</p>
<p>struct AnyToPython{<br>
static PyObject* convert(boost::any x) {<br>
if( size_t *sizet = boost::any_cast&lt;size_t&gt;(&amp;x)){<br>
return Py_BuildValue("n", *sizet);<br>
}else if( double *d = boost::any_cast&lt;double&gt;(&amp;x)){<br>
return Py_BuildValue("d", *d);<br>
}else{<br>
std::cerr &lt;&lt; "convert failed! Unkown type! Will return None! Please modify AnyToPython" &lt;&lt; std::endl;<br>
return Py_BuildValue("s", (char *)0);<br>
}<br>
}<br>
};</p>
<p></p>
<p>/*</p>
<p>* 新定义一个普通函数,包装原TestBase::setParam函数,注意第一个、第三个参数</p>
<p>* 需要在python文件中,对Test.setParam复制,而不是在这里直接引出Test::setParam函数</p>
<p>*/</p>
<p>bool setParam(const boost::shared_ptr&lt;TestBase&gt;&amp; indicator, const std::string&amp; name, object o){<br>
boost::any tmp;<br>
extract&lt;size_t&gt; x1(o);<br>
if( x1.check() ){<br>
tmp = x1();<br>
indicator-&gt;setParam(name, tmp);<br>
return true;<br>
}<br><br>
extract&lt;double&gt; x2(o);<br>
if( x2.check() ){<br>
tmp = x2();<br>
indicator-&gt;setParam(name, tmp);<br>
return true;<br>
}<br><br>
return false;<br>
}</p>
<p>BOOST_PYTHON_MODULE(_test){</p>
<p> class_&lt;TestBase&gt;("Test")</p>
<p> .def("getParam", &amp;TestBase.getParam)</p>
<p> ;</p>
<p></p>
<p> to_python_converter&lt;boost::any, AnyToPython&gt;();</p>
<p> def("setParam", setParam);</p>
<p>}</p>
<p></p>
<p>在相应的python文件中(如test.py):</p>
<p>from _test import *</p>
<p>Test.setParam = setParam #解决Test::setParam问题</p>

你可能感兴趣的:(python)