c++和Python互操作進階應用程式(5)

來源:互聯網
上載者:User

把我在實際過程中遇到的問題,總結一下,請先閱讀:python教程,python FAQ

1.如果封裝的c++類沒有拷貝建構函式怎麼辦?
定義class的時候,加入模板參數boost::noncopyable,同時指定no_init

  1.  class_<ExpandEmitter,boost::noncopyable>("ExpandEmitter",no_init);

拷貝構造的目的是,c++對象執行個體傳遞給python時,可以通過拷貝構造重新構造一個python中使用的對象執行個體。一般如果沒有拷貝構造,需要boost的share_ptr來傳遞共用指標。

2.封裝的c++函數如何返回指標或者引用?
return_value_policy<return_by_reference>(),傳回值原則設定為return_by_reference即可

  1.  .def("getPostData",&Request::getPostData,return_value_policy<return_by_reference>()) 

3.自訂的String怎麼和python進行自動轉換?
http://www.maycode.com/boostdoc/boost-doc/libs/python/doc/v2/faq.html#custom_string

 

struct template_string_to_python_str<br />{<br /> static PyObject* convert(TemplateString const& s)<br /> {<br /> return boost::python::incref(boost::python::object(s.ptr()).ptr());<br /> }<br />};</p><p>struct template_string_from_python_str<br />{<br /> template_string_from_python_str()<br /> {<br /> boost::python::converter::registry::push_back(<br /> &convertible,<br /> &construct,<br /> boost::python::type_id<TemplateString>());<br /> }</p><p> static void* convertible(PyObject* obj_ptr)<br /> {<br /> if (!PyString_Check(obj_ptr))<br /> {<br /> return 0;<br /> }<br /> return obj_ptr;<br /> }</p><p> static void construct(<br /> PyObject* obj_ptr, boost::python::converter::rvalue_from_python_stage1_data* data)<br /> {<br /> const char* value = PyString_AsString(obj_ptr);<br /> if (value == 0)<br /> boost::python::throw_error_already_set();<br /> void* storage = (<br /> (boost::python::converter::rvalue_from_python_storage<TemplateString>*)<br /> data)->storage.bytes;<br /> new (storage) TemplateString(value);<br /> data->convertible = storage;<br /> }<br /> };</p><p>BOOST_PYTHON_MODULE(ctemplate)<br />{<br /> boost::python::to_python_converter<<br /> TemplateString,<br /> template_string_to_python_str>();</p><p> template_string_from_python_str();<br />}

4.對象釋放的問題
假如在c++中建立的對象,在python中怎麼釋放?或者在python中建立的對象,在c++怎麼釋放?
我的看法是,在一種語言中建立並釋放。如果你想在python中建立對象,可以調用c++的函數,比如newClass()來建立,返回一個指標或者引用,使用完畢,調用c++的deleteClass()來釋放。否則,python引用計數會特別麻煩,很容易導致記憶體流失等問題。

5.共用指標,怎麼手工釋放?
共用指標,預設是自動釋放的,但是有時候,我們並不需要自動釋放,想自己手工釋放,可以定義一個釋放函數,在建立共用指標的時候,傳入釋放函數指標。

  1. //定義
  2. typedef boost::shared_ptr < World > world_ptr;
  3. //定義一個釋放函數
  4. void deleteWorld(World* w);
  5. //共用指標,傳入釋放函數指標
  6. world_ptr worldObjectPtr (new World,deleteWorld);

6.c++封裝模組,多個檔案include,怎麼會有多重定義的問題?

  1. BOOST_PYTHON_MODULE(hello)
  2. {
  3.       class_ <World>("World")
  4.           .def("greet", &World::greet)
  5.           .def("set", &World::set)
  6.       ;
  7.       register_ptr_to_python <world_ptr>();
  8. }

如果上面這段在.h檔案中,多個cpp檔案引用是不行的。這個時候,可以定義一個標頭檔如下

  1. extern "C" void inithello();

你在標頭檔中首先聲明inithello(),在把上面的移到cpp中,BOOST_PYTHON_MODULE會實現一個函數inithello(),這樣就可以了。

7.如何封裝c++容器?
boost/python/suite/indexing目錄下的標頭檔

  1. //include
  2. #include <boost/python/suite/indexing/map_indexing_suite.hpp>
  3. //定義模組時,可以定義map
  4.    //String map
  5.     boost::python::class_<std::map<std::String,std::String> >("StrMap")
  6.         .def(map_indexing_suite<std::map<std::String,std::String> >())

本人研究過一段時間並在實際項目中應用,寫出這個系列希望對大家有協助。
系列文章:
Python調用C/C++函數(1)
Python調用採用Boost Python封裝的c++(2)
C++調用Python(3)
C++調用Python(4)
c++和Python互操作進階應用程式(5)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.