pygccxml-development Mailing List for C++ Python language bindings (Page 20)
Brought to you by:
mbaas,
roman_yakovenko
You can subscribe to this list here.
2006 |
Jan
|
Feb
(6) |
Mar
(160) |
Apr
(96) |
May
(152) |
Jun
(72) |
Jul
(99) |
Aug
(189) |
Sep
(161) |
Oct
(110) |
Nov
(9) |
Dec
(3) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2007 |
Jan
(13) |
Feb
(48) |
Mar
(35) |
Apr
(7) |
May
(37) |
Jun
(8) |
Jul
(15) |
Aug
(8) |
Sep
(2) |
Oct
(1) |
Nov
(2) |
Dec
(38) |
2008 |
Jan
(11) |
Feb
(29) |
Mar
(17) |
Apr
(3) |
May
|
Jun
(64) |
Jul
(49) |
Aug
(51) |
Sep
(18) |
Oct
(22) |
Nov
(9) |
Dec
(9) |
2009 |
Jan
(28) |
Feb
(15) |
Mar
(2) |
Apr
(11) |
May
(6) |
Jun
(2) |
Jul
(3) |
Aug
(34) |
Sep
(5) |
Oct
(7) |
Nov
(13) |
Dec
(14) |
2010 |
Jan
(39) |
Feb
(3) |
Mar
(3) |
Apr
(14) |
May
(11) |
Jun
(8) |
Jul
(9) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2011 |
Jan
|
Feb
|
Mar
(7) |
Apr
|
May
|
Jun
(3) |
Jul
(3) |
Aug
(3) |
Sep
|
Oct
|
Nov
|
Dec
|
2015 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
(1) |
Sep
|
Oct
|
Nov
|
Dec
(2) |
2016 |
Jan
(1) |
Feb
(1) |
Mar
|
Apr
(1) |
May
|
Jun
|
Jul
(1) |
Aug
(1) |
Sep
|
Oct
|
Nov
(1) |
Dec
|
2019 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
(1) |
Sep
|
Oct
|
Nov
|
Dec
(1) |
2020 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
(1) |
Sep
|
Oct
|
Nov
|
Dec
(1) |
2021 |
Jan
(1) |
Feb
(1) |
Mar
|
Apr
|
May
(1) |
Jun
|
Jul
|
Aug
|
Sep
(1) |
Oct
(1) |
Nov
|
Dec
|
From: Roman Y. <rom...@gm...> - 2008-04-07 13:32:11
|
---------- Forwarded message ---------- From: Roman Yakovenko <rom...@gm...> Date: Mon, Apr 7, 2008 at 4:31 PM Subject: Re: [pygccxml-commit] string type mismatch between python and C++ To: Johnson Lu <joh...@op...> On Mon, Apr 7, 2008 at 9:55 AM, Johnson Lu <joh...@op...> wrote: > Hello Mr. Yakovenko: Roman is just fine :-) > The compiler I am using is VC 7.1, and we also use the openTop > libraries. > > I am wrapping a class that is part of a large multi-platform product, > and in our product we have some fairly convoluted header includes that, > I think, make strings into different types base on the platform being > compiled on. On VC7.1 simple string became unsigned shorts (heaven only > knows). > > Here is a simple snippet of that function as generated by PY++: > > struct ClassificationOutput_wrapper : ClassificationOutput, bp::wrapper< > ClassificationOutput > { > . > . > . > virtual void setApplicationName( ::ot::String const & > applicationName ) { > if( bp::override func_setApplicationName = this->get_override( > "setApplicationName" ) ) > func_setApplicationName( applicationName ); > else > this->ClassificationOutput::setApplicationName( > applicationName ); > } > void default_setApplicationName( ::ot::String const & > applicationName ) { > ClassificationOutput::setApplicationName( applicationName ); > } > . > . > . > } > BOOST_PYTHON_MODULE(pyplusplus){ > bp::class_< ClassificationOutput_wrapper, boost::noncopyable >( > "ClassificationOutput" ) > .def( bp::init< >() ) > . > . > . > .def( > "setApplicationName" > , &::ClassificationOutput::setApplicationName > , &ClassificationOutput_wrapper::default_setApplicationName > , ( bp::arg("applicationName") ) ) > > > And here is the original .h snippet for the function... > > class ClassificationBuiltinImplDeclSpec ClassificationOutput : public > IClassificationModifiableOutput > { > . > . > . > virtual void setApplicationName(const String& applicationName) ; > > And my test code simply creates a C++ ClassificationOutput object: > > ClassificationOutput mm; > mm.setApplicationName(OPTIER_T("monty python")); > mm.setUserName(OPTIER_T("jclu")); > . > . > . > bpl::object pyCls(boost::ref(mm)); > main_namespace["output"] = pyCls; > > Pass it to Python via name space addition to the python dictionary, then > used a simple python code: > output.setApplicationName("anApplication") # and this line does > not work. > output.getUserName() # returns jclu, so python can read from > C++ > > All seem very straight forward, except not quite so, for me. > > Again, really appreciate your help. Okey, I think I understand the problem and was able to reproduce it. Solution: 1. http://boost.org/doc/libs/1_35_0/libs/python/doc/v2/faq.html#custom_string 2. http://language-binding.net/pyplusplus/documentation/inserting_code.html#insert-code-to-module Explanation: I guess Boost.Python was compiled with "Yes (/Zc:wchar_t)" option turned on. Thus class std::basic_string< unsigned short > and std::basic_string< wchar_t > are 2 different classes. So you will have to define your own string conversion or recompile all your source code with the option. HTH -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ |
From: Roman Y. <rom...@gm...> - 2008-03-30 05:42:09
|
On Sat, Mar 29, 2008 at 9:28 PM, Matthias Baas <mat...@gm...> wrote: > Hi, Hello > I have a problem wrapping a template class whose member functions have > default values that are objects of a template type... well, what I mean > is best shown on an example: > > class A > { > public: > int v; > }; > > template<class T> > class B > { > T value; > public: > B(T a=T()) : value(a) {} > > void foo(T a=T()) {} > }; > > inline void instantiation() > { > B<A> b; > } > > > When I create bindings for classes A and B, Py++ produces source code > that doesn't compile. > The problem is the default value in the constructor of B and the foo() > method. The values are instances of template class T which should be A > in the above example. But Py++ actually writes "T()" into the source > code which, of course, is not declared and produces a compile error. > I suppose in a case like this Py++ should recognize that the expression > for the default value uses a template type and replace it with the > actual type that was used in the instantiation. > I don't know if this is easy to do, but I could imagine that it is not > quite trivial... > > So what do you think, could Py++ handle this all alone or do I have to > replace the default value myself somehow? Py++ couldn't handle this :-(. I suggest you to read this thread(http://www.gccxml.org/pipermail/gccxml/2008-February/001059.html). -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ |
From: Matthias B. <mat...@gm...> - 2008-03-29 19:28:09
|
Hi, I have a problem wrapping a template class whose member functions have default values that are objects of a template type... well, what I mean is best shown on an example: class A { public: int v; }; template<class T> class B { T value; public: B(T a=T()) : value(a) {} void foo(T a=T()) {} }; inline void instantiation() { B<A> b; } When I create bindings for classes A and B, Py++ produces source code that doesn't compile. The problem is the default value in the constructor of B and the foo() method. The values are instances of template class T which should be A in the above example. But Py++ actually writes "T()" into the source code which, of course, is not declared and produces a compile error. I suppose in a case like this Py++ should recognize that the expression for the default value uses a template type and replace it with the actual type that was used in the instantiation. I don't know if this is easy to do, but I could imagine that it is not quite trivial... So what do you think, could Py++ handle this all alone or do I have to replace the default value myself somehow? Cheers, - Matthias - |
From: Roman Y. <rom...@gm...> - 2008-03-27 18:37:21
|
Mo, I need to see the original or very close to it source code. I can generate the code by myself :-) If this is an open source project it is enough to post URL. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ |
From: Simon W. <wim...@go...> - 2008-03-27 12:26:56
|
This is the generated code: // This file has been generated by Py++. #include "boost/python.hpp" #include "__array_1.pypp.hpp" #include "boost/python/suite/indexing/vector_indexing_suite.hpp" #include "c:/micropather/micropather.h" namespace bp = boost::python; struct Graph_wrapper : micropather::Graph, bp::wrapper< micropather::Graph > { Graph_wrapper() : micropather::Graph() , bp::wrapper< micropather::Graph >(){ // null constructor } virtual void AdjacentCost( void * state, ::std::vector< micropather::StateCost > * adjacent ){ bp::override func_AdjacentCost = this->get_override( "AdjacentCost" ); func_AdjacentCost( state, boost::python::ptr(adjacent) ); } virtual float LeastCostEstimate( void * stateStart, void * stateEnd ){ bp::override func_LeastCostEstimate = this->get_override( "LeastCostEstimate" ); return func_LeastCostEstimate( stateStart, stateEnd ); } virtual void PrintStateInfo( void * state ){ bp::override func_PrintStateInfo = this->get_override( "PrintStateInfo" ); func_PrintStateInfo( state ); } }; struct NodeCost_wrapper : micropather::NodeCost, bp::wrapper< micropather::NodeCost > { NodeCost_wrapper(micropather::NodeCost const & arg ) : micropather::NodeCost( arg ) , bp::wrapper< micropather::NodeCost >(){ // copy constructor } NodeCost_wrapper() : micropather::NodeCost() , bp::wrapper< micropather::NodeCost >(){ // null constructor } static ::micropather::PathNode * get_node(micropather::NodeCost const & inst ){ return inst.node; } static void set_node( micropather::NodeCost & inst, ::micropather::PathNode * new_value ){ inst.node = new_value; } }; struct PathNode_wrapper : micropather::PathNode, bp::wrapper< micropather::PathNode > { static pyplusplus::containers::static_sized::array_1_t< ::micropather::NodeCost, 4> pyplusplus_adjacent_wrapper( ::micropather::PathNode & inst ){ return pyplusplus::containers::static_sized::array_1_t< ::micropather::NodeCost, 4>( inst.adjacent ); } unsigned int get_inClosed() const { return inClosed; } void set_inClosed( unsigned int new_value ){ inClosed = new_value; } unsigned int get_inOpen() const { return inOpen; } void set_inOpen( unsigned int new_value ){ inOpen = new_value; } static ::micropather::PathNode * get_left(micropather::PathNode const & inst ){ return inst.left; } static void set_left( micropather::PathNode & inst, ::micropather::PathNode * new_value ){ inst.left = new_value; } static ::micropather::PathNode * get_next(micropather::PathNode const & inst ){ return inst.next; } static void set_next( micropather::PathNode & inst, ::micropather::PathNode * new_value ){ inst.next = new_value; } static ::micropather::PathNode * get_parent(micropather::PathNode const & inst ){ return inst.parent; } static void set_parent( micropather::PathNode & inst, ::micropather::PathNode * new_value ){ inst.parent = new_value; } static ::micropather::PathNode * get_prev(micropather::PathNode const & inst ){ return inst.prev; } static void set_prev( micropather::PathNode & inst, ::micropather::PathNode * new_value ){ inst.prev = new_value; } }; BOOST_PYTHON_MODULE(micropather){ bp::class_< std::vector< void* > >("vector_less__void_ptr___grate_") .def( bp::vector_indexing_suite< ::std::vector< void* > >() ); { //::std::vector< micropather::StateCost > typedef bp::class_< std::vector< micropather::StateCost > > vector_less__micropather_scope_StateCost__grate__exposer_t; vector_less__micropather_scope_StateCost__grate__exposer_t vector_less__micropather_scope_StateCost__grate__exposer = vector_less__micropather_scope_StateCost__grate__exposer_t( "vector_less__micropather_scope_StateCost__grate_" ); bp::scope vector_less__micropather_scope_StateCost__grate__scope( vector_less__micropather_scope_StateCost__grate__exposer ); //WARNING: the next line of code will not compile, because "::micropather::StateCost" does not have operator== ! //vector_less__micropather_scope_StateCost__grate__exposer.def( bp::vector_indexing_suite< ::std::vector< micropather::StateCost > >() ); } bp::class_< Graph_wrapper, boost::noncopyable >( "Graph" ) .def( "AdjacentCost" , bp::pure_virtual( &::micropather::Graph::AdjacentCost ) , ( bp::arg("state"), bp::arg("adjacent") ) ) .def( "LeastCostEstimate" , bp::pure_virtual( &::micropather::Graph::LeastCostEstimate ) , ( bp::arg("stateStart"), bp::arg("stateEnd") ) ) .def( "PrintStateInfo" , bp::pure_virtual( &::micropather::Graph::PrintStateInfo ) , ( bp::arg("state") ) ); { //::micropather::MicroPather typedef bp::class_< micropather::MicroPather, boost::noncopyable > MicroPather_exposer_t; MicroPather_exposer_t MicroPather_exposer = MicroPather_exposer_t( "MicroPather", bp::init< micropather::Graph *, bp::optional< unsigned int > >(( bp::arg("graph"), bp::arg("allocate")=(unsigned int)(250) )) ); bp::scope MicroPather_scope( MicroPather_exposer ); bp::scope().attr("SOLVED") = (int)micropather::MicroPather::SOLVED; bp::scope().attr("NO_SOLUTION") = (int)micropather::MicroPather::NO_SOLUTION; bp::scope().attr("START_END_SAME") = (int)micropather::MicroPather::START_END_SAME; { //::micropather::MicroPather::Checksum typedef ::UPTR ( ::micropather::MicroPather::*Checksum_function_type )( ) ; MicroPather_exposer.def( "Checksum" , Checksum_function_type( &::micropather::MicroPather::Checksum ) ); } { //::micropather::MicroPather::DumpHashTable typedef void ( ::micropather::MicroPather::*DumpHashTable_function_type )( ) ; MicroPather_exposer.def( "DumpHashTable" , DumpHashTable_function_type( &::micropather::MicroPather::DumpHashTable ) ); } { //::micropather::MicroPather::Reset typedef void ( ::micropather::MicroPather::*Reset_function_type )( ) ; MicroPather_exposer.def( "Reset" , Reset_function_type( &::micropather::MicroPather::Reset ) ); } { //::micropather::MicroPather::Solve typedef int ( ::micropather::MicroPather::*Solve_function_type )( void *,void *,::std::vector< void* > *,float * ) ; MicroPather_exposer.def( "Solve" , Solve_function_type( &::micropather::MicroPather::Solve ) , ( bp::arg("startState"), bp::arg("endState"), bp::arg("path"), bp::arg("totalCost") ) ); } { //::micropather::MicroPather::StatesInPool typedef void ( ::micropather::MicroPather::*StatesInPool_function_type )( ::std::vector< void* > * ) ; MicroPather_exposer.def( "StatesInPool" , StatesInPool_function_type( &::micropather::MicroPather::StatesInPool ) , ( bp::arg("stateVec") ) ); } } bp::class_< NodeCost_wrapper >( "NodeCost" ) .def_readwrite( "cost", µpather::NodeCost::cost ) .add_property( "node" , bp::make_function( (::micropather::PathNode * (*)( ::micropather::NodeCost const & ))(&NodeCost_wrapper::get_node), bp::return_internal_reference< >() ) , bp::make_function( (void (*)( ::micropather::NodeCost &,::micropather::PathNode * ))(&NodeCost_wrapper::set_node), bp::with_custodian_and_ward_postcall< 1, 2 >() ) ); { //::micropather::PathNode typedef bp::class_< PathNode_wrapper, boost::noncopyable > PathNode_exposer_t; PathNode_exposer_t PathNode_exposer = PathNode_exposer_t( "PathNode", bp::no_init ); bp::scope PathNode_scope( PathNode_exposer ); bp::scope().attr("MAX_CACHE") = (int)micropather::PathNode::MAX_CACHE; { //::micropather::PathNode::AddBefore typedef void ( ::micropather::PathNode::*AddBefore_function_type )( ::micropather::PathNode * ) ; PathNode_exposer.def( "AddBefore" , AddBefore_function_type( &::micropather::PathNode::AddBefore ) , ( bp::arg("addThis") ) ); } { //::micropather::PathNode::Init typedef void ( ::micropather::PathNode::*Init_function_type )( unsigned int,void *,float,float,::micropather::PathNode * ) ; PathNode_exposer.def( "Init" , Init_function_type( &::micropather::PathNode::Init ) , ( bp::arg("_frame"), bp::arg("_state"), bp::arg("_costFromStart"), bp::arg("_estToGoal"), bp::arg("_parent") ) ); } { //::micropather::PathNode::Reuse typedef void ( ::micropather::PathNode::*Reuse_function_type )( unsigned int,float,float,::micropather::PathNode * ) ; PathNode_exposer.def( "Reuse" , Reuse_function_type( &::micropather::PathNode::Reuse ) , ( bp::arg("_frame"), bp::arg("_costFromStart"), bp::arg("_estToGoal"), bp::arg("_parent") ) ); } { //::micropather::PathNode::Unlink typedef void ( ::micropather::PathNode::*Unlink_function_type )( ) ; PathNode_exposer.def( "Unlink" , Unlink_function_type( &::micropather::PathNode::Unlink ) ); } pyplusplus::containers::static_sized::register_array_1< ::micropather::NodeCost, 4, bp::return_internal_reference< > >( "__array_1__scope_micropather_scope_NodeCost_4" ); { //micropather::PathNode::adjacent [variable], type=micropather::NodeCost[4] typedef pyplusplus::containers::static_sized::array_1_t< ::micropather::NodeCost, 4> ( *array_wrapper_creator )( ::micropather::PathNode & ); PathNode_exposer.add_property( "adjacent" , bp::make_function( array_wrapper_creator(&PathNode_wrapper::pyplusplus_adjacent_wrapper) , bp::with_custodian_and_ward_postcall< 0, 1 >() ) ); } PathNode_exposer.def_readwrite( "costFromStart", µpather::PathNode::costFromStart ); PathNode_exposer.def_readwrite( "estToGoal", µpather::PathNode::estToGoal ); PathNode_exposer.def_readwrite( "frame", µpather::PathNode::frame ); PathNode_exposer.add_property( "inClosed" , (unsigned int ( PathNode_wrapper::* )( ) const)(&PathNode_wrapper::get_inClosed) , (void ( PathNode_wrapper::* )( unsigned int ) )(&PathNode_wrapper::set_inClosed) ); PathNode_exposer.add_property( "inOpen" , (unsigned int ( PathNode_wrapper::* )( ) const)(&PathNode_wrapper::get_inOpen) , (void ( PathNode_wrapper::* )( unsigned int ) )(&PathNode_wrapper::set_inOpen) ); PathNode_exposer.add_property( "left" , bp::make_function( (::micropather::PathNode * (*)( ::micropather::PathNode const & ))(&PathNode_wrapper::get_left), bp::return_internal_reference< >() ) , bp::make_function( (void (*)( ::micropather::PathNode &,::micropather::PathNode * ))(&PathNode_wrapper::set_left), bp::with_custodian_and_ward_postcall< 1, 2 >() ) ); PathNode_exposer.add_property( "next" , bp::make_function( (::micropather::PathNode * (*)( ::micropather::PathNode const & ))(&PathNode_wrapper::get_next), bp::return_internal_reference< >() ) , bp::make_function( (void (*)( ::micropather::PathNode &,::micropather::PathNode * ))(&PathNode_wrapper::set_next), bp::with_custodian_and_ward_postcall< 1, 2 >() ) ); PathNode_exposer.def_readwrite( "numAdjacent", µpather::PathNode::numAdjacent ); PathNode_exposer.add_property( "parent" , bp::make_function( (::micropather::PathNode * (*)( ::micropather::PathNode const & ))(&PathNode_wrapper::get_parent), bp::return_internal_reference< >() ) , bp::make_function( (void (*)( ::micropather::PathNode &,::micropather::PathNode * ))(&PathNode_wrapper::set_parent), bp::with_custodian_and_ward_postcall< 1, 2 >() ) ); PathNode_exposer.add_property( "prev" , bp::make_function( (::micropather::PathNode * (*)( ::micropather::PathNode const & ))(&PathNode_wrapper::get_prev), bp::return_internal_reference< >() ) , bp::make_function( (void (*)( ::micropather::PathNode &,::micropather::PathNode * ))(&PathNode_wrapper::set_prev), bp::with_custodian_and_ward_postcall< 1, 2 >() ) ); PathNode_exposer.def_readwrite( "totalCost", µpather::PathNode::totalCost ); } bp::class_< micropather::StateCost >( "StateCost" ) .def_readwrite( "cost", µpather::StateCost::cost ); bp::scope().attr("FLT_BIG") = micropather::FLT_BIG; } |
From: Roman Y. <rom...@gm...> - 2008-03-27 11:49:38
|
On Thu, Mar 27, 2008 at 1:39 PM, Alexander Eisenhuth <st...@st...> wrote: > Roman Yakovenko schrieb: > > > In order to give better answer source code is needed. > > > >> Afterward I get this error: > >> Fehler 6 error C2248: "micropather::PathNode::~PathNode": Kein Zugriff auf > >> private Member, dessen Deklaration in der micropather::PathNode-Klasse > >> erfolgte. c:\program files > >> (x86)\boost\boost_1_34_1\boost\python\detail\destroy.hpp 33 > > > > Can you translate the error message to English? > > 'member' : cannot access 'access' member declared in class 'class' > > Taken from: > > (http://msdn2.microsoft.com/en-us/library/tsbce2bh(VS.80).aspx) Thanks. If I understand right, the code doesn't compile because class has private/protected constructor. In this case Py++ had to place "no_init" in boost::python::class_ constructor. If this not happens, than I guess there is a bug here. P.S. I prefer to see the code and errors, so I could analyze the whole picture and not to guess. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ |
From: Alexander E. <st...@st...> - 2008-03-27 11:40:04
|
Roman Yakovenko schrieb: > In order to give better answer source code is needed. > >> Afterward I get this error: >> Fehler 6 error C2248: "micropather::PathNode::~PathNode": Kein Zugriff auf >> private Member, dessen Deklaration in der micropather::PathNode-Klasse >> erfolgte. c:\program files >> (x86)\boost\boost_1_34_1\boost\python\detail\destroy.hpp 33 > > Can you translate the error message to English? 'member' : cannot access 'access' member declared in class 'class' Taken from: (http://msdn2.microsoft.com/en-us/library/tsbce2bh(VS.80).aspx) |
From: Roman Y. <rom...@gm...> - 2008-03-27 11:03:17
|
On Thu, Mar 27, 2008 at 12:35 PM, Simon Wimmer <wim...@go...> wrote: > I´m new to py++ and I want to start getting into it by wrapping micropather, > a A* implemantation. It only consists of a header and a source file so it > should be easy to do. > So I used the py++ gui to get the py++ code. Trying to compile it I got an > C2874 error that there is a problem with an operator. I expected this as in > the line above there was an comment: > > //WARNING: the next line of code will not compile, because > "::micropather::StateCost" does not have operator== ! > So I simply commented out the error line. This leads me to my first > question. How could I have achieved this with py++? Right now there is a thread that discuss similar problem, on boost.python mailing list http://mail.python.org/pipermail/c++-sig/2008-March/subject.html In order to give better answer source code is needed. > Afterward I get this error: > Fehler 6 error C2248: "micropather::PathNode::~PathNode": Kein Zugriff auf > private Member, dessen Deklaration in der micropather::PathNode-Klasse > erfolgte. c:\program files > (x86)\boost\boost_1_34_1\boost\python\detail\destroy.hpp 33 Can you translate the error message to English? Thanks -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ |
From: Simon W. <wim...@go...> - 2008-03-27 10:35:29
|
I´m new to py++ and I want to start getting into it by wrapping micropather, a A* implemantation. It only consists of a header and a source file so it should be easy to do. So I used the py++ gui to get the py++ code. Trying to compile it I got an C2874 error that there is a problem with an operator. I expected this as in the line above there was an comment: //WARNING: the next line of code will not compile, because "::micropather::StateCost" does not have operator== ! So I simply commented out the error line. This leads me to my first question. How could I have achieved this with py++? Afterward I get this error: Fehler 6 error C2248: "micropather::PathNode::~PathNode": Kein Zugriff auf private Member, dessen Deklaration in der micropather::PathNode-Klasse erfolgte. c:\program files (x86)\boost\boost_1_34_1\boost\python\detail\destroy.hpp 33 How could I sort out that one? Also I´m confused by another thing. Trying ou the code from the introduction: mb.calldefs( access_type_matcher_t( 'protected' ) ).exclude() I get an errror with: access_type_matcher_t('protected'). What exactly does this access_type_matcher_t thingy mean. Looking at the source I get instructed to look at decl_wrappers.scopdef_t, but that completley confuses me. |
From: Roman Y. <rom...@gm...> - 2008-03-18 07:40:26
|
On Mon, Mar 17, 2008 at 11:12 PM, Matthias Baas <mat...@gm...> wrote: > By the way, here's another (minor) thing I noticed about the warnings > that Py++ generates. When you wrap a function that actually takes > Boost.Python types as input or returns them as output, then Py++ > generates a warning that, for example, boost::python::list is not > exposed and this might lead to errors at runtime. But of course, the > list object is a built-in Boost.Python type, so this one doesn't need to > be wrapped. So it would be nice if Py++ would be aware of the > Boost.Python types and could suppress those warnings. At the moment, I > don't have many warnings, so it's not such a big issue but I guess as a > project grows you might get more and more of those which makes it harder > to spot "real" warnings. Thanks, I will fix this before next release. Py++ has nice interface for warning disabling: http://language-binding.net/pyplusplus/documentation/warnings.html HTH -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ |
From: Matthias B. <mat...@gm...> - 2008-03-17 21:12:20
|
Roman Yakovenko wrote: > Matthias unfortunately the problem is on the GCCXML side > > I don't see any work around to the problem :-(. It seems that template > constructors of template class is a special case, that GCCXML > could\does not treat. Yes, unfortunately. I noticed that it doesn't appear in the generated XML file. I was just hoping there's a different way of instantiating the class that might change things. > I think the best solution in this case is to add "constructor > declaration" to the classes. ok, thanks. If only constructors are affected by this then it's not that bad. By the way, here's another (minor) thing I noticed about the warnings that Py++ generates. When you wrap a function that actually takes Boost.Python types as input or returns them as output, then Py++ generates a warning that, for example, boost::python::list is not exposed and this might lead to errors at runtime. But of course, the list object is a built-in Boost.Python type, so this one doesn't need to be wrapped. So it would be nice if Py++ would be aware of the Boost.Python types and could suppress those warnings. At the moment, I don't have many warnings, so it's not such a big issue but I guess as a project grows you might get more and more of those which makes it harder to spot "real" warnings. - Matthias - |
From: Roman Y. <rom...@gm...> - 2008-03-17 12:05:16
|
On Sun, Mar 16, 2008 at 11:08 PM, Matthias Baas <mat...@gm...> wrote: > Hi, Hello. Welcome back. > after being away from the "wrapping business" for quite a while I'm now > back and trying to wrap another library that is heavily template based. > As I'm starting from scratch, I'm now using the official module builder > instead of my own version. > So as a first general question, is there meanwhile some special support > for templates? Can I tell Py++ what template arguments to use and it > takes care of instantiating it? > I'm assuming that's not (yet) the case, so I was instantiating the stuff > myself. > But I ran into a problem with a template constructor inside a template > class. I could only wrap the non-template constructors whereas the other > ones don't seem to be reported by gccxml. > Here is an example: > > ///////////////////// File: header.h > template<class T> > class Spam > { > T x; > T y; > public: > > Spam() : x(0),y(0) {} > template<class V> > Spam(V a, V b) : x(a),y(b) {} > }; > > // Instantiate the template > inline void dummy() > { > Spam<double> c0(1, 2); > } > > ####################### File: generate.py > > from pyplusplus.module_builder import module_builder_t > > mb = module_builder_t(files = ['header.h']) > > spam = mb.class_("Spam<double>") > spam.include() > > # Print all declarations that are available on the class > decls = spam.decls() > for decl in decls: > print decl > > mb.build_code_creator(module_name="spammod") > mb.split_module(dir_name="bindings") > > > When I run the Python script, the declarations that get printed are the > following: > > Spam<double>::Spam(Spam<double> const & arg0) [copy constructor] > Spam<double>::Spam() [constructor] > Spam<double>::x [variable] > Spam<double>::y [variable] > > I would also have expected a constructor that takes two ints, but it > isn't there and so it isn't wrapped. Is there another way to instantiate > the class that would make the constructor visible? Matthias unfortunately the problem is on the GCCXML side I don't see any work around to the problem :-(. It seems that template constructors of template class is a special case, that GCCXML could\does not treat. I think the best solution in this case is to add "constructor declaration" to the classes. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ |
From: Matthias B. <mat...@gm...> - 2008-03-16 21:08:17
|
Hi, after being away from the "wrapping business" for quite a while I'm now back and trying to wrap another library that is heavily template based. As I'm starting from scratch, I'm now using the official module builder instead of my own version. So as a first general question, is there meanwhile some special support for templates? Can I tell Py++ what template arguments to use and it takes care of instantiating it? I'm assuming that's not (yet) the case, so I was instantiating the stuff myself. But I ran into a problem with a template constructor inside a template class. I could only wrap the non-template constructors whereas the other ones don't seem to be reported by gccxml. Here is an example: ///////////////////// File: header.h template<class T> class Spam { T x; T y; public: Spam() : x(0),y(0) {} template<class V> Spam(V a, V b) : x(a),y(b) {} }; // Instantiate the template inline void dummy() { Spam<double> c0(1, 2); } ####################### File: generate.py from pyplusplus.module_builder import module_builder_t mb = module_builder_t(files = ['header.h']) spam = mb.class_("Spam<double>") spam.include() # Print all declarations that are available on the class decls = spam.decls() for decl in decls: print decl mb.build_code_creator(module_name="spammod") mb.split_module(dir_name="bindings") When I run the Python script, the declarations that get printed are the following: Spam<double>::Spam(Spam<double> const & arg0) [copy constructor] Spam<double>::Spam() [constructor] Spam<double>::x [variable] Spam<double>::y [variable] I would also have expected a constructor that takes two ints, but it isn't there and so it isn't wrapped. Is there another way to instantiate the class that would make the constructor visible? I'm using the latest official versions of pygccxml/pyplusplus and gccxml from cvs (and everything is on OSX 10.4.11). Cheers, - Matthias - |
From: Roman Y. <rom...@gm...> - 2008-03-03 20:23:42
|
On Mon, Mar 3, 2008 at 7:01 AM, Kevin Watters <kev...@gm...> wrote: > > The fix in SVN. > > After trying your change from SVN I still get the same error: > > /Users/kevin/src/boost_1_34_1/boost/python/object/value_holder.hpp:66: > error: cannot declare field > 'boost::python::objects::value_holder<wxWindowBase_wrapper>::m_held' > to be of abstract type 'wxWindowBase_wrapper' > ../src/generated/WindowBase.pypp.cpp:9: note: because the following > virtual functions are pure within 'wxWindowBase_wrapper': > /Users/kevin/src/wxWidgets/include/wx/window.h:1278: note: virtual > NSView* wxWindowBase::GetHandle() const > /Users/kevin/src/wxWidgets/include/wx/window.h:1511: note: virtual > void wxWindowBase::DoClientToScreen(int*, int*) const > /Users/kevin/src/wxWidgets/include/wx/window.h:1512: note: virtual > void wxWindowBase::DoScreenToClient(int*, int*) const > /Users/kevin/src/wxWidgets/include/wx/window.h:1517: note: virtual > void wxWindowBase::DoCaptureMouse() > /Users/kevin/src/wxWidgets/include/wx/window.h:1518: note: virtual > void wxWindowBase::DoReleaseMouse() > /Users/kevin/src/wxWidgets/include/wx/window.h:1521: note: virtual > void wxWindowBase::DoGetPosition(int*, int*) const > /Users/kevin/src/wxWidgets/include/wx/window.h:1523: note: virtual > void wxWindowBase::DoGetSize(int*, int*) const > /Users/kevin/src/wxWidgets/include/wx/window.h:1524: note: virtual > void wxWindowBase::DoGetClientSize(int*, int*) const > /Users/kevin/src/wxWidgets/include/wx/window.h:1536: note: virtual > void wxWindowBase::DoSetSize(int, int, int, int, int) > /Users/kevin/src/wxWidgets/include/wx/window.h:1539: note: virtual > void wxWindowBase::DoSetClientSize(int, int) > /Users/kevin/src/wxWidgets/include/wx/window.h:1553: note: virtual > void wxWindowBase::DoMoveWindow(int, int, int, int) > /Users/kevin/src/wxWidgets/include/wx/window.h:1565: note: virtual > bool wxWindowBase::DoPopupMenu(wxMenu*, int, int) > make: *** [obj-gnu/wxpy_WindowBase_pypp.o] Error 1 > > I'm trying to understand what the change you made to > class_wrapper.redefined_funcs is doing. If I get anywhere I will let > you know. Can you create small test case, that reproduce the problem? I tried to create without success: http://pygccxml.svn.sourceforge.net/viewvc/pygccxml?view=rev&revision=1268 http://pygccxml.svn.sourceforge.net/viewvc/pygccxml?view=rev&revision=1269 http://pygccxml.svn.sourceforge.net/viewvc/pygccxml?view=rev&revision=1270 Thanks. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ |
From: Kevin W. <kev...@gm...> - 2008-03-03 05:01:21
|
> The fix in SVN. After trying your change from SVN I still get the same error: /Users/kevin/src/boost_1_34_1/boost/python/object/value_holder.hpp:66: error: cannot declare field 'boost::python::objects::value_holder<wxWindowBase_wrapper>::m_held' to be of abstract type 'wxWindowBase_wrapper' ../src/generated/WindowBase.pypp.cpp:9: note: because the following virtual functions are pure within 'wxWindowBase_wrapper': /Users/kevin/src/wxWidgets/include/wx/window.h:1278: note: virtual NSView* wxWindowBase::GetHandle() const /Users/kevin/src/wxWidgets/include/wx/window.h:1511: note: virtual void wxWindowBase::DoClientToScreen(int*, int*) const /Users/kevin/src/wxWidgets/include/wx/window.h:1512: note: virtual void wxWindowBase::DoScreenToClient(int*, int*) const /Users/kevin/src/wxWidgets/include/wx/window.h:1517: note: virtual void wxWindowBase::DoCaptureMouse() /Users/kevin/src/wxWidgets/include/wx/window.h:1518: note: virtual void wxWindowBase::DoReleaseMouse() /Users/kevin/src/wxWidgets/include/wx/window.h:1521: note: virtual void wxWindowBase::DoGetPosition(int*, int*) const /Users/kevin/src/wxWidgets/include/wx/window.h:1523: note: virtual void wxWindowBase::DoGetSize(int*, int*) const /Users/kevin/src/wxWidgets/include/wx/window.h:1524: note: virtual void wxWindowBase::DoGetClientSize(int*, int*) const /Users/kevin/src/wxWidgets/include/wx/window.h:1536: note: virtual void wxWindowBase::DoSetSize(int, int, int, int, int) /Users/kevin/src/wxWidgets/include/wx/window.h:1539: note: virtual void wxWindowBase::DoSetClientSize(int, int) /Users/kevin/src/wxWidgets/include/wx/window.h:1553: note: virtual void wxWindowBase::DoMoveWindow(int, int, int, int) /Users/kevin/src/wxWidgets/include/wx/window.h:1565: note: virtual bool wxWindowBase::DoPopupMenu(wxMenu*, int, int) make: *** [obj-gnu/wxpy_WindowBase_pypp.o] Error 1 I'm trying to understand what the change you made to class_wrapper.redefined_funcs is doing. If I get anywhere I will let you know. - Kevin |
From: Kevin W. <kev...@gm...> - 2008-03-01 21:25:46
|
> I always thought that Py++ generates code that compiles even if "pure > virtual" functions are excluded. I just added new test and saw that > this is not the case. > > I will fix the problem in next few days. > > Thanks for bug reporting. Thank you very much for this! I'll probably be hunting sooner than that for the cause of this--I'll let you know if I find anything ;) > > In the class hierachy I'm attempting to get something working with, > > there is an entire category of classes (all with one common base > > class) that are "owned" entirely by C++ > I need to think a little about this. It could be nice if you can > create small test case, so I could play with it. I really appreciate your help so far. I made a small demo of what I'm talking about specifically: A small set of classes that mirror the ones I'm trying to wrap: http://code.google.com/p/wxpy/source/browse/trunk/docs/window_lifetimes/window_lifetime.h And some example Python and C++ for interacting with those classes: http://code.google.com/p/wxpy/source/browse/trunk/docs/window_lifetimes/window_lifetime.cpp If nothing else I hope it helps you understand what I mean. Thanks again! - Kevin |
From: Roman Y. <rom...@gm...> - 2008-03-01 20:03:56
|
On Sat, Mar 1, 2008 at 8:03 PM, Kevin Watters <kev...@gm...> wrote: > Say I have > > class A { > public: > virtual void DoSomething() = 0; > }; > > and > > class B { > public: > void Something() { /* ... */ } > virtual void DoSomething() { Something(); } > }; > > I want to hide the DoSomething methods from Python, but keep Something exposed. > > So I do > > mb.calldefs(lambda d: d.name.startswith('Do')).exclude() > > to hide the DoSomethings(). The problem is, class A has other methods > that I need, so I use A.include() to include it. So you can change the order of exclude's > I get compile errors, saying "cannot instantiate abstract class." I > think what is happening, is that by excluding the pure virtual > functions in A, I'm fooling Py++ into generating invalid wrappers for > A (since all the pure virtual functions are "hidden"). Does "exclude" > work this way? I always thought that Py++ generates code that compiles even if "pure virtual" functions are excluded. I just added new test and saw that this is not the case. I will fix the problem in next few days. Thanks for bug reporting. > If not, Py++ must be getting confused about some other > aspect of the classes and I'll have to investigate further. > (Ideally what I really want is to finalize ALL classes unless I say so > explicitly that a method should be overridden. This seems ideal for > performance. I found the finalize function in the contrib folder, and > it seems to work, but I'm still not sure how to handle the more > complex case outlined above.) As I said: I will fix the bug. > I also have another, entirely unrelated question :-D And you will get entirely unrelated answer :-) > In the class hierachy I'm attempting to get something working with, > there is an entire category of classes (all with one common base > class) that are "owned" entirely by C++, since they have operating > system window resources. When you create a button, for instance, you > attach it to a window, and the window is responsible for destroying > it. You call something like window->Destroy(), and then the Python > reference to the button has to become "invalid." > > The other wrapper for this GUI library that exists (created with SWIG) > has a clever solution where the __class__ of the object is assigned to > a special "DeadObject" class, and any further attribute accesses on > the object raise Exceptions (instead of crash the program ;) ). I'm > having trouble figuring out to achieve this kind of behavior with > boost. Basically, the object lifetime of a wxButton, for instance, is > not at all determined by any python objects which may reference it. > It's constructor takes a wxWindow* parent which immediately gains > ownership of the wxButton, and Destroys its children when it is > Destroyed. If the Python reference to the button goes away, nothing at > all should happen. How does that idea fit into Boost's object > lifetime management, if at all? I need to think a little about this. It could be nice if you can create small test case, so I could play with it. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ |
From: Kevin W. <kev...@gm...> - 2008-03-01 18:03:11
|
Say I have class A { public: virtual void DoSomething() = 0; }; and class B { public: void Something() { /* ... */ } virtual void DoSomething() { Something(); } }; I want to hide the DoSomething methods from Python, but keep Something exposed. So I do mb.calldefs(lambda d: d.name.startswith('Do')).exclude() to hide the DoSomethings(). The problem is, class A has other methods that I need, so I use A.include() to include it. I get compile errors, saying "cannot instantiate abstract class." I think what is happening, is that by excluding the pure virtual functions in A, I'm fooling Py++ into generating invalid wrappers for A (since all the pure virtual functions are "hidden"). Does "exclude" work this way? If not, Py++ must be getting confused about some other aspect of the classes and I'll have to investigate further. (Ideally what I really want is to finalize ALL classes unless I say so explicitly that a method should be overridden. This seems ideal for performance. I found the finalize function in the contrib folder, and it seems to work, but I'm still not sure how to handle the more complex case outlined above.) I also have another, entirely unrelated question :-D In the class hierachy I'm attempting to get something working with, there is an entire category of classes (all with one common base class) that are "owned" entirely by C++, since they have operating system window resources. When you create a button, for instance, you attach it to a window, and the window is responsible for destroying it. You call something like window->Destroy(), and then the Python reference to the button has to become "invalid." The other wrapper for this GUI library that exists (created with SWIG) has a clever solution where the __class__ of the object is assigned to a special "DeadObject" class, and any further attribute accesses on the object raise Exceptions (instead of crash the program ;) ). I'm having trouble figuring out to achieve this kind of behavior with boost. Basically, the object lifetime of a wxButton, for instance, is not at all determined by any python objects which may reference it. It's constructor takes a wxWindow* parent which immediately gains ownership of the wxButton, and Destroys its children when it is Destroyed. If the Python reference to the button goes away, nothing at all should happen. How does that idea fit into Boost's object lifetime management, if at all? On Thu, Feb 28, 2008 at 2:55 PM, Roman Yakovenko <rom...@gm...> wrote: > On Thu, Feb 28, 2008 at 7:33 PM, Kevin Watters <kev...@gm...> wrote: > > I'm using Py++ with a complex class hierarchy with lots of virtual methods. > > It should not be a problem > > > > As one example, wxWindow inherits from wxObject. But Py++ is > > generating class wrappers which don't reflect any inheritance at all. > > The class declaration for wxWindow looks like > > > > bp::class_< wxWindow, boost::noncopyable >( "Window" ) > > .def( bp::init< >() ) > > .def( bp::init< wxWindow *, wxWindowID, bp::optional< wxPoint > > const &, wxSize const &, long int, wxString const & > >(( > > bp::arg("parent"), bp::arg("winid"), bp::arg("pos")=wxDefaultPosition, > > bp::arg("size")=wxDefaultSize, bp::arg("style")=(long int)(0), > > bp::arg("name")=wxString(wxPanelNameStr) )) ) > > > > > > Note the missing bp::bases. > > > > Oddly enough, if I load up a module builder in a console and query > > wxWindow for its bases with the "recursive_bases" property, I see that > > pygccxml has successively pulled out a chain of classes that looks > > correct: "wxWindow -> wxCocoaNSView -> wxWindowBase -> wxEvtHandler -> > > wxTrackable -> wxObject" > > > > By which criteria does Py++ decide to expose inhertiance? Do I need to > > "include" each of the classes listed in wxWindow's recursive_bases > > property? What if I want just the wxObject methods to be exposed? > > I read your script. I think I understand what the problem is. > Take a look on this document. > http://language-binding.net/pyplusplus/documentation/tutorials/module_builder/module_builder.html#declarations-customization > > I guess this is the problem. You can check it by testing "ignore" value > > mb.class_( 'wxObject' ).ignore > > Basically I suggest you to exclude everything and than to include all > declarations you want to expose. > mb = module_builder_t(...) > mb.global_ns.exclude() > > mb.classes( lambda decl: decl.startswith( 'wx' ) ).include() > > > > > (For reference, my code generator is at > > http://code.google.com/p/wxpy/source/browse/trunk/generate_code.py) > > Why do you use so much try...except blocks? > > For example: > try: mb.mem_funs(name = 'CloneGDIRefData').exclude() > except: pass > > If the function is there Py++ will find it an exclude, if it not > there, than exception will be thrown and you will be noted that the > were some changes in source files? > > I ask, because I want to understand whether the problem in Py++ > interface or this is just your use case. > > > > Any help is much appreciated! > > HTH > > -- > Roman Yakovenko > C++ Python language binding > http://www.language-binding.net/ > |
From: Kevin W. <kev...@gm...> - 2008-02-29 00:17:59
|
> I guess this is the problem. You can check it by testing "ignore" value > > mb.class_( 'wxObject' ).ignore This helps--because like you suggest, I started out by excluding all declarations and then slowly moving things in so that I could keep the number of errors under control. With this ignore property, I noticed that some of the bases of wxFrame, for instance, were being excluded. I was under the impression that mb.class_('wxFrame').include() would include all the bases of wxFrame as well--but apparently that is not the case. > Why do you use so much try...except blocks? > > For example: > try: mb.mem_funs(name = 'CloneGDIRefData').exclude() > except: pass I've developing this simultaneously on OS X and Windows, and some of the methods differ--or are missing entirely, depending on the platform. Thanks again for your help! - Kevin |
From: Roman Y. <rom...@gm...> - 2008-02-28 19:54:56
|
On Thu, Feb 28, 2008 at 7:33 PM, Kevin Watters <kev...@gm...> wrote: > I'm using Py++ with a complex class hierarchy with lots of virtual methods. It should not be a problem > As one example, wxWindow inherits from wxObject. But Py++ is > generating class wrappers which don't reflect any inheritance at all. > The class declaration for wxWindow looks like > > bp::class_< wxWindow, boost::noncopyable >( "Window" ) > .def( bp::init< >() ) > .def( bp::init< wxWindow *, wxWindowID, bp::optional< wxPoint > const &, wxSize const &, long int, wxString const & > >(( > bp::arg("parent"), bp::arg("winid"), bp::arg("pos")=wxDefaultPosition, > bp::arg("size")=wxDefaultSize, bp::arg("style")=(long int)(0), > bp::arg("name")=wxString(wxPanelNameStr) )) ) > > > Note the missing bp::bases. > > Oddly enough, if I load up a module builder in a console and query > wxWindow for its bases with the "recursive_bases" property, I see that > pygccxml has successively pulled out a chain of classes that looks > correct: "wxWindow -> wxCocoaNSView -> wxWindowBase -> wxEvtHandler -> > wxTrackable -> wxObject" > > By which criteria does Py++ decide to expose inhertiance? Do I need to > "include" each of the classes listed in wxWindow's recursive_bases > property? What if I want just the wxObject methods to be exposed? I read your script. I think I understand what the problem is. Take a look on this document. http://language-binding.net/pyplusplus/documentation/tutorials/module_builder/module_builder.html#declarations-customization I guess this is the problem. You can check it by testing "ignore" value mb.class_( 'wxObject' ).ignore Basically I suggest you to exclude everything and than to include all declarations you want to expose. mb = module_builder_t(...) mb.global_ns.exclude() mb.classes( lambda decl: decl.startswith( 'wx' ) ).include() > (For reference, my code generator is at > http://code.google.com/p/wxpy/source/browse/trunk/generate_code.py) Why do you use so much try...except blocks? For example: try: mb.mem_funs(name = 'CloneGDIRefData').exclude() except: pass If the function is there Py++ will find it an exclude, if it not there, than exception will be thrown and you will be noted that the were some changes in source files? I ask, because I want to understand whether the problem in Py++ interface or this is just your use case. > Any help is much appreciated! HTH -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ |
From: Kevin W. <kev...@gm...> - 2008-02-28 17:33:03
|
I'm using Py++ with a complex class hierarchy with lots of virtual methods. As one example, wxWindow inherits from wxObject. But Py++ is generating class wrappers which don't reflect any inheritance at all. The class declaration for wxWindow looks like bp::class_< wxWindow, boost::noncopyable >( "Window" ) .def( bp::init< >() ) .def( bp::init< wxWindow *, wxWindowID, bp::optional< wxPoint const &, wxSize const &, long int, wxString const & > >(( bp::arg("parent"), bp::arg("winid"), bp::arg("pos")=wxDefaultPosition, bp::arg("size")=wxDefaultSize, bp::arg("style")=(long int)(0), bp::arg("name")=wxString(wxPanelNameStr) )) ) Note the missing bp::bases. Oddly enough, if I load up a module builder in a console and query wxWindow for its bases with the "recursive_bases" property, I see that pygccxml has successively pulled out a chain of classes that looks correct: "wxWindow -> wxCocoaNSView -> wxWindowBase -> wxEvtHandler -> wxTrackable -> wxObject" By which criteria does Py++ decide to expose inhertiance? Do I need to "include" each of the classes listed in wxWindow's recursive_bases property? What if I want just the wxObject methods to be exposed? (For reference, my code generator is at http://code.google.com/p/wxpy/source/browse/trunk/generate_code.py) Any help is much appreciated! |
From: Roman Y. <rom...@gm...> - 2008-02-28 15:39:17
|
On Thu, Feb 28, 2008 at 5:21 PM, Kevin Watters <kev...@gm...> wrote: > I'm using "cache = directory_cache_t('cache')" in my module_builder_t > constructor, and it does cut down on the parse time that would > otherwise occur, but it still takes around 10 seconds for each .h > file--and since my project is only growing in size, the time it takes > to get through all the header files is becoming prohibitively long. > > Before I go hacking on the cache stuff, I wanted to ask here--is there > a specific reason why the hash of a header file, plus all the > preprocessor defines and include paths, are not enough to recognize an > already parsed header file? Recognizing these should be an operation > that takes less than a second, I would think--but some of them take as > long as ten. > > Does anyone else have any suggestions on cutting down the turnaround > time for a growing Py++ project? I am: http://language-binding.net/pyplusplus/documentation/how_to/best_practices.html HTH -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ |
From: Kevin W. <kev...@gm...> - 2008-02-28 15:21:43
|
I'm using "cache = directory_cache_t('cache')" in my module_builder_t constructor, and it does cut down on the parse time that would otherwise occur, but it still takes around 10 seconds for each .h file--and since my project is only growing in size, the time it takes to get through all the header files is becoming prohibitively long. Before I go hacking on the cache stuff, I wanted to ask here--is there a specific reason why the hash of a header file, plus all the preprocessor defines and include paths, are not enough to recognize an already parsed header file? Recognizing these should be an operation that takes less than a second, I would think--but some of them take as long as ten. Does anyone else have any suggestions on cutting down the turnaround time for a growing Py++ project? |
From: Kevin W. <kev...@gm...> - 2008-02-26 16:00:14
|
> mb = module_builder_t( ... ) > #find wxWindow constructor with 6 arguments of any type > wxWindow = mb.constructor( 'wxWindow', arg_types=[None]*6 ) > wxWindow.arguments[-1].default_value = 'wxString( wxPanelNameStr )' > > This should be enough. Thanks for this! It was exactly what I was looking for. And since wxWidgets follows a very clear convention with all of these globals that were causing problems, I took care of all them at once with a clever declaration matcher. > I also will check whether Py++ can generate better code in this use-case. I couldn't find enough documentation on bp::arg to know whether this was an odd case, or if it has trouble with coercing types with implicit constructors of any kind--but I'd imagine there's a general solution lurking about somewhere. Thanks again. |
From: Roman Y. <rom...@gm...> - 2008-02-26 07:01:38
|
On Tue, Feb 26, 2008 at 2:11 AM, Kevin Watters <kev...@gm...> wrote: > I'm new to Py++ but I've been experimenting with wrapping wxWidgets, > the cross platform GUI library. Let me know if you need help with this. > It has gone fairly well, but I'm getting the following error and I'm > not sure how to resolve it. > > In a header file somewhere, a global called "wxPanelNameStr" is declared: > > extern WXDLLEXPORT_DATA(const char) wxPanelNameStr[]; > > The implementation is in a CPP file somewhere else: > > extern WXDLLEXPORT_DATA(const char) wxPanelNameStr[] = "panel"; > > My problem arises in a constructor which uses wxPanelNameStr as the > default value for one of its arguments: > > inline wxWindow(wxWindow *parent, wxWindowID winid, > const wxPoint& pos = wxDefaultPosition, > const wxSize& size = wxDefaultSize, > long style = 0, > const wxString& name = wxPanelNameStr) > > Py++ generates the following code for this: > > .def( bp::init< wxWindow *, wxWindowID, bp::optional< wxPoint > const &, wxSize const &, long int, wxString const & > >(( > bp::arg("parent"), bp::arg("winid"), bp::arg("pos")=wxDefaultPosition, > bp::arg("size")=wxDefaultSize, bp::arg("style")=(long int)(0), > bp::arg("name")=wxPanelNameStr )) ); > > You'll note that the sixth argument takes a value of type const > wxString&, but the default argument in the generated code is const > char []. The error I get is long and does lots of complaining about > convertables and char[], but ultimately I think it boils down to this > line: > > ../boost_1_34_1/boost/python/type_id.hpp:88: error: invalid use of > array with unspecified bounds > > wxString does have a constructor which takes const char*, so the > implicit conversion should happen, but I think Boost::Python is > getting confused. > > Does anyone know how I can resolve this? mb = module_builder_t( ... ) #find wxWindow constructor with 6 arguments of any type wxWindow = mb.constructor( 'wxWindow', arg_types=[None]*6 ) wxWindow.arguments[-1].default_value = 'wxString( wxPanelNameStr )' This should be enough. I also will check whether Py++ can generate better code in this use-case. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ |