c++和Python互操作高级应用(5)
2008-09-22 16:34
639 查看
把我在实际过程中遇到的问题,总结一下,请先阅读:python教程,python FAQ
1.如果封装的c++类没有拷贝构造函数怎么办?
定义class的时候,加入模板参数boost::noncopyable,同时指定no_init
class_<ExpandEmitter,boost::noncopyable>("ExpandEmitter",no_init);
拷贝构造的目的是,c++对象实例传递给python时,可以通过拷贝构造重新构造一个python中使用的对象实例。一般如果没有拷贝构造,需要boost的share_ptr来传递共享指针。
2.封装的c++函数如何返回指针或者引用?
return_value_policy<return_by_reference>(),返回值策略设置为return_by_reference即可
.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
4.对象释放的问题
假如在c++中创建的对象,在python中怎么释放?或者在python中创建的对象,在c++怎么释放?
我的看法是,在一种语言中创建并释放。如果你想在python中创建对象,可以调用c++的函数,比如newClass()来创建,返回一个指针或者引用,使用完毕,调用c++的deleteClass()来释放。否则,python引用计数会特别麻烦,很容易导致内存泄漏等问题。
5.共享指针,怎么手工释放?
共享指针,默认是自动释放的,但是有时候,我们并不需要自动释放,想自己手工释放,可以定义一个释放函数,在创建共享指针的时候,传入释放函数指针。
//定义
typedef boost::shared_ptr < World > world_ptr;
//定义一个释放函数
void deleteWorld(World* w);
//共享指针,传入释放函数指针
world_ptr worldObjectPtr (new World,deleteWorld);
6.c++封装模块,多个文件include,怎么会有多重定义的问题?
BOOST_PYTHON_MODULE(hello)
{
class_ <World>("World")
.def("greet", &World::greet)
.def("set", &World::set)
;
register_ptr_to_python <world_ptr>();
}
如果上面这段在.h文件中,多个cpp文件引用是不行的。这个时候,可以定义一个头文件如下
extern "C" void inithello();
你在头文件中首先声明inithello(),在把上面的移到cpp中,BOOST_PYTHON_MODULE会实现一个函数inithello(),这样就可以了。
7.如何封装c++容器?
boost/python/suite/indexing目录下的头文件
//include
#include <boost/python/suite/indexing/map_indexing_suite.hpp>
//定义模块时,可以定义map
//String map
boost::python::class_<std::map<std::String,std::String> >("StrMap")
.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)
1.如果封装的c++类没有拷贝构造函数怎么办?
定义class的时候,加入模板参数boost::noncopyable,同时指定no_init
class_<ExpandEmitter,boost::noncopyable>("ExpandEmitter",no_init);
拷贝构造的目的是,c++对象实例传递给python时,可以通过拷贝构造重新构造一个python中使用的对象实例。一般如果没有拷贝构造,需要boost的share_ptr来传递共享指针。
2.封装的c++函数如何返回指针或者引用?
return_value_policy<return_by_reference>(),返回值策略设置为return_by_reference即可
.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 { static PyObject* convert(TemplateString const& s) { return boost::python::incref(boost::python::object(s.ptr()).ptr()); } }; struct template_string_from_python_str { template_string_from_python_str() { boost::python::converter::registry::push_back( &convertible, &construct, boost::python::type_id<TemplateString>()); } static void* convertible(PyObject* obj_ptr) { if (!PyString_Check(obj_ptr)) { return 0; } return obj_ptr; } static void construct( PyObject* obj_ptr, boost::python::converter::rvalue_from_python_stage1_data* data) { const char* value = PyString_AsString(obj_ptr); if (value == 0) boost::python::throw_error_already_set(); void* storage = ( (boost::python::converter::rvalue_from_python_storage<TemplateString>*) data)->storage.bytes; new (storage) TemplateString(value); data->convertible = storage; } }; BOOST_PYTHON_MODULE(ctemplate) { boost::python::to_python_converter< TemplateString, template_string_to_python_str>(); template_string_from_python_str(); }
4.对象释放的问题
假如在c++中创建的对象,在python中怎么释放?或者在python中创建的对象,在c++怎么释放?
我的看法是,在一种语言中创建并释放。如果你想在python中创建对象,可以调用c++的函数,比如newClass()来创建,返回一个指针或者引用,使用完毕,调用c++的deleteClass()来释放。否则,python引用计数会特别麻烦,很容易导致内存泄漏等问题。
5.共享指针,怎么手工释放?
共享指针,默认是自动释放的,但是有时候,我们并不需要自动释放,想自己手工释放,可以定义一个释放函数,在创建共享指针的时候,传入释放函数指针。
//定义
typedef boost::shared_ptr < World > world_ptr;
//定义一个释放函数
void deleteWorld(World* w);
//共享指针,传入释放函数指针
world_ptr worldObjectPtr (new World,deleteWorld);
6.c++封装模块,多个文件include,怎么会有多重定义的问题?
BOOST_PYTHON_MODULE(hello)
{
class_ <World>("World")
.def("greet", &World::greet)
.def("set", &World::set)
;
register_ptr_to_python <world_ptr>();
}
如果上面这段在.h文件中,多个cpp文件引用是不行的。这个时候,可以定义一个头文件如下
extern "C" void inithello();
你在头文件中首先声明inithello(),在把上面的移到cpp中,BOOST_PYTHON_MODULE会实现一个函数inithello(),这样就可以了。
7.如何封装c++容器?
boost/python/suite/indexing目录下的头文件
//include
#include <boost/python/suite/indexing/map_indexing_suite.hpp>
//定义模块时,可以定义map
//String map
boost::python::class_<std::map<std::String,std::String> >("StrMap")
.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)
相关文章推荐
- c++和Python互操作高级应用
- c++和Python互操作高级应用(5)
- Python(应用) — Excel操作(一)
- Python高级应用实例对比:高效计算大文件中的最长行的长度
- 从Java到C++——常量(const)的高级应用
- python模块介绍- shutil 高级文件操作
- python中列表的操作与应用
- MySql数据库数据更新操作其高级应用
- dotcloud 托管 python web应用 第二章 mysql数据库操作
- multiprocessing在python中的高级应用-共享数据与同步
- 零基础学python-10.1 序列赋值高级应用
- ESP32学习microPython之(3)--高级应用
- 分布式缓存技术redis学习系列(四)——redis高级应用(集群搭建、集群分区原理、集群操作)
- Python(列表操作应用实战)方法二
- Python学习笔记——文件操作、综合应用
- python -- 装饰器的高级应用
- python中threading的高级函数应用解析 Lock Rlock Condition Semaphore Timer Event Semaphore对象
- 给有C或C++基础的Python入门 :Python Crash Course 4 操作列表 4.1--4.3
- 分布式缓存技术redis学习系列(四)——redis高级应用(集群搭建、集群分区原理、集群操作)
- Python学习入门基础教程(learning Python)--5.6 Python读文件操作高级