|
View:
New views
10 Messages
—
Rating Filter:
Alert me
|
|
|
[C++-sig] Base class defined in other header file not included in bp::bases<>Hi Folks,
I’m having some trouble generating boost-python wrapper code using pyplusplus for a derived class which has one of its base classes defined in another file.
Simple scenario:
mydir/ other.hpp: class baseB{ };
hierarchy.hpp:
#include "other.hpp" class baseA{ }; class derivedC: public baseA, public baseB{ };
generate_code.py: import os from pyplusplus import module_builder
mb = module_builder.module_builder_t( files=['hierarchy.hpp'] ) mb.build_code_creator( module_name='inherit' ) mb.code_creator.user_defined_directories.append( os.path.abspath('.') ) mb.write_module('boost_hierarchy.cpp')
------------------------------------------------------------------------------------------------------------------------- Generated code (boost_hierarchy.cpp) looks like this:
// This file has been generated by pyplusplus. #include "boost/python.hpp" #include "hierarchy.hpp"
namespace bp = boost::python;
BOOST_PYTHON_MODULE(inherit){ bp::class_< baseA >( "baseA" );
bp::class_< derivedC, bp::bases< baseA > >( "derivedC" ); }
How can I get pyplusplus to add ‘baseB’ to bp::bases<> for ‘derivedC’ class when ‘baseB’ class is defined in another file (present in the same directory or different directory)?
When I move the definition of ‘baseB’ class to hierarchy.hpp, boost wrapper for ‘derivedC’ is correctly generated as: bp::class_< derivedC, bp::bases< baseA, baseB > >( "derivedC" );
Thanks, -Meghana.
_______________________________________________ C++-sig mailing list C++-sig@... http://mail.python.org/mailman/listinfo/c++-sig |
|
|
Re: [C++-sig] Base class defined in other header file not included in bp::bases<>On 7/13/06, Haridev, Meghana <mharidev@...> wrote:
> Hi Folks, > I'm having some trouble generating boost-python wrapper code using > pyplusplus for a derived class which has one of its base classes defined in > another file. > How can I get pyplusplus to add 'baseB' to bp::bases<> for 'derivedC' class > when 'baseB' class is defined in another file (present in the same directory If "other.hpp" presents in the same directory it will just work. > or different directory)? In this case baseB class will be excluded. The idea behind such behaviour is next: there is one directory that contains library interface and many directories that contain implementation details. So, by default pyplusplus excludes from generation all declarations defined in other directories. You can find more information here: http://language-binding.net/pyplusplus/tutorials/module_builder/module_builder.html Next few lines of code will include baseB: mb = module_builder_t( ... ) mb.class_( 'baseB' ).include() #or if you want to include all declarations from directory Y: mb.decls( header_dir=Y ).include() I hope, this will help you. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ _______________________________________________ C++-sig mailing list C++-sig@... http://mail.python.org/mailman/listinfo/c++-sig |
|
|
Re: [C++-sig] Base class defined in other header file not includedin bp::bases<>Hi Roman, Thanks for your help!
Another question:
Say that I have already written manually boost-python wrappers for baseB class (present in different directory) and have a shared library for it.
Now I want to use pyplusplus to generate the boost-python wrappers for derivedC class.
Like you suggested, if I add: mb.class_( 'baseB' ).include() It will give me the following generated code:
bp::class_< baseB >( "baseB" ); bp::class_< baseA >( "baseA" ); bp::class_< derivedC, bp::bases< baseA, baseB > >( "derivedC" );
But what if I don't want pyplusplus to expose baseB again (I am going to link baseB’s shared library with derivedC’s boost wrapper) but I still want it to appear in bp::bases - is it possible to do that using pyplusplus?
In other words, I want the generated code to look like this:
/* bp::class_< baseB >( "baseB" ); - Do not want to generate */ bp::class_< baseA >( "baseA" ); bp::class_< derivedC, bp::bases< baseA, baseB > >( "derivedC" );
Thanks, -Meghana.
-----Original Message-----
On 7/13/06, Haridev, Meghana <mharidev@...> wrote: > Hi Folks, > I'm having some trouble generating boost-python wrapper code using > pyplusplus for a derived class which has one of its base classes defined in > another file.
> How can I get pyplusplus to add 'baseB' to bp::bases<> for 'derivedC' class > when 'baseB' class is defined in another file (present in the same directory
If "other.hpp" presents in the same directory it will just work.
> or different directory)?
In this case baseB class will be excluded. The idea behind such behaviour is next: there is one directory that contains library interface and many directories that contain implementation details. So, by default pyplusplus excludes from generation all declarations defined in other directories. You can find more information here: http://language-binding.net/pyplusplus/tutorials/module_builder/module_builder.html
Next few lines of code will include baseB:
mb = module_builder_t( ... ) mb.class_( 'baseB' ).include() #or if you want to include all declarations from directory Y: mb.decls( header_dir=Y ).include()
I hope, this will help you.
-- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ _______________________________________________ C++-sig mailing list http://mail.python.org/mailman/listinfo/c++-sig _______________________________________________ C++-sig mailing list C++-sig@... http://mail.python.org/mailman/listinfo/c++-sig |
|
|
Re: [C++-sig] Base class defined in other header file not includedin bp::bases<>On 7/13/06, Haridev, Meghana <mharidev@...> wrote:
> In other words, I want the generated code to look like this: > /* bp::class_< baseB >( "baseB" ); - Do not want to generate */ > > bp::class_< baseA >( "baseA" ); > > bp::class_< derivedC, bp::bases< baseA, baseB > >( "derivedC" ); It is possible, but you will have to understand a little how code creators works. There are few ways to solve the problem. 1. Exclude baseB from being generated, and add it manually to derivedC. Take a look on pyplusplus/code_creators/class_declaration.py - class "class_t", method - _generate_bases. You will have to redefine this method, something like this: def my_generate_bases( self, base_creators ): if self.declaration.Name != 'derivedC': run current code else: your logic is going her pyplusplus.code_creators.class_t._generate_bases = my_generate_bases 2. You can include baseB to be generated, but instead of generating code it will generate empty string: mb = module_builder_t( ... ) mb.build_code_creators( ... ) from pyplusplus import code_creators baseB = mb.class_( 'baseB' ) baseB_creators \ = code_creators.creator_finder.find_by_declaration( lambda decl: decl is baseB #what to look , mb.code_creator ) #where #now, we have to leave only class_t and class_wrapper_t code creators relevant_clss = ( code_creators.class_t, code_creators.class_wrapper_t ) baseB_creators = filters( lambda c: isinstance( c, relevant_clss ) ) for c in baseB_creators: c.create = lambda self: '' Second approach is better, because in this case pyplusplus will take into account all data available from baseB, but will not generate code. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ _______________________________________________ C++-sig mailing list C++-sig@... http://mail.python.org/mailman/listinfo/c++-sig |
|
|
Re: [C++-sig] Base class defined in other header file notincludedin bp::bases<>Hi Roman,
I tried your second approach since it goes better with our environment. I made some changes (highlighted in bold below) to get it to run. It works fine till I come to the point where I need to write the module to multiple files (or even just a single file).
mb = module_builder_t( ... ) mb.class_('baseB').include() #because baseB defined in header file in diff directory mb.build_code_creators( ... )
from pyplusplus import code_creators
baseB = mb.class_( 'baseB' ) baseB_creators \ = code_creators.creator_finder.find_by_declaration( lambda decl: decl is baseB #what to look , mb.code_creator ) #where
#now, we have to leave only class_t and class_wrapper_t code creators relevant_clss = ( code_creators.class_t, code_creators.class_wrapper_t )
baseB_creators = filter( lambda c: isinstance( c, relevant_clss ), baseB_creators )
for c in baseB_creators: c.create = lambda self: ''
mb.split_module( os.path.abspath('.') )
I get this error:
File "generate_code.py", line 80, in export mb.split_module( os.path.abspath('.') ) File "…pyplusplus/module_builder/builder.py", line 224, in split_module file_writers.write_multiple_files( self.code_creator, dir_name ) File "…pyplusplus/file_writers/__init__.py", line 32, in write_multiple_files mfs.write() File "…pyplusplus/file_writers/multiple_files.py", line 253, in write map( self.split_class, class_creators ) File "…pyplusplus/file_writers/multiple_files.py", line 171, in split_class self.__split_class_impl( class_creator ) File "…pyplusplus/file_writers/multiple_files.py", line 148, in __split_class_impl , [class_creator] )) File "…pyplusplus/file_writers/multiple_files.py", line 126, in create_source answer.append( creator.wrapper.create() ) TypeError: <lambda>() takes exactly 1 argument (0 given)
Seems like it doesn’t like the empty string we give to create…
I also tried just writing the module to a single file: mb.write_module( os.path.join( os.path.abspath('.'), settings.module_name + '.cpp' ) )
File “…pyplusplus/module_builder/builder.py", line 215, in write_module file_writers.write_file( self.code_creator, file_name ) File "…pyplusplus/file_writers/__init__.py", line 28, in write_file sf.write() File "…pyplusplus/file_writers/single_file.py", line 24, in write self.write_file( self.file_name, self.extmodule.create() ) File "…pyplusplus/code_creators/code_creator.py", line 93, in create code = self._create_impl() File "…pyplusplus/code_creators/module.py", line 195, in _create_impl code = compound.compound_t.create_internal_code( self.creators[index:] ) File "…pyplusplus/code_creators/compound.py", line 56, in create_internal_code internals = map( lambda expr: expr.create(), creators ) File "…pyplusplus/code_creators/compound.py", line 56, in <lambda> internals = map( lambda expr: expr.create(), creators ) TypeError: <lambda>() takes exactly 1 argument (0 given)
Any suggestions?
Thanks, -Meghana.
-----Original Message-----
On 7/13/06, Haridev, Meghana <mharidev@...> wrote: > In other words, I want the generated code to look like this: > /* bp::class_< baseB >( "baseB" ); - Do not want to generate */ > > bp::class_< baseA >( "baseA" ); > > bp::class_< derivedC, bp::bases< baseA, baseB > >( "derivedC" );
It is possible, but you will have to understand a little how code creators works. There are few ways to solve the problem.
1. Exclude baseB from being generated, and add it manually to derivedC. Take a look on pyplusplus/code_creators/class_declaration.py - class "class_t", method - _generate_bases. You will have to redefine this method, something like this:
def my_generate_bases( self, base_creators ): if self.declaration.Name != 'derivedC': run current code else: your logic is going her
pyplusplus.code_creators.class_t._generate_bases = my_generate_bases
2. You can include baseB to be generated, but instead of generating code it will generate empty string:
mb = module_builder_t( ... ) mb.build_code_creators( ... )
from pyplusplus import code_creators
baseB = mb.class_( 'baseB' )
baseB_creators \ = code_creators.creator_finder.find_by_declaration( lambda decl: decl is baseB #what to look , mb.code_creator ) #where #now, we have to leave only class_t and class_wrapper_t code creators relevant_clss = ( code_creators.class_t, code_creators.class_wrapper_t ) baseB_creators = filters( lambda c: isinstance( c, relevant_clss ) ) for c in baseB_creators: c.create = lambda self: ''
Second approach is better, because in this case pyplusplus will take into account all data available from baseB, but will not generate code.
-- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ _______________________________________________ C++-sig mailing list http://mail.python.org/mailman/listinfo/c++-sig _______________________________________________ C++-sig mailing list C++-sig@... http://mail.python.org/mailman/listinfo/c++-sig |
|
|
Re: [C++-sig] Base class defined in other header file notincludedin bp::bases<>On 7/26/06, Haridev, Meghana <mharidev@...> wrote:
> for c in baseB_creators: > > c.create = lambda self: '' ^^^^^^^^^^^^^^^^^^^^^ c.create = lambda: '' Please try this, it should work. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ _______________________________________________ C++-sig mailing list C++-sig@... http://mail.python.org/mailman/listinfo/c++-sig |
|
|
Re: [C++-sig] Base class defined in other header file notincludedinbp::bases<>Great - that works :-)
Thanks for your help! -----Original Message----- From: c++-sig-bounces@... [mailto:c++-sig-bounces@...] On Behalf Of Roman Yakovenko Sent: Wednesday, July 26, 2006 12:07 PM To: Development of Python/C++ integration Subject: Re: [C++-sig] Base class defined in other header file notincludedinbp::bases<> On 7/26/06, Haridev, Meghana <mharidev@...> wrote: > for c in baseB_creators: > > c.create = lambda self: '' ^^^^^^^^^^^^^^^^^^^^^ c.create = lambda: '' Please try this, it should work. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ _______________________________________________ C++-sig mailing list C++-sig@... http://mail.python.org/mailman/listinfo/c++-sig _______________________________________________ C++-sig mailing list C++-sig@... http://mail.python.org/mailman/listinfo/c++-sig |
|
|
Re: [C++-sig] Base class defined in other header file notincludedinbp::bases<>On 7/26/06, Haridev, Meghana <mharidev@...> wrote:
> Great - that works :-) > Thanks for your help! Enjoy. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ _______________________________________________ C++-sig mailing list C++-sig@... http://mail.python.org/mailman/listinfo/c++-sig |
|
|
Re: [C++-sig] Base class defined in other header file not includedin bp::bases<>I have a few questions about this thread. Basically I have the same problem, my bases for a binding are not getting picked up cause they are in a separate library.
I've tried solution #2 and here's a snippet from the Py++ generator file: <<Start Snippet================================================================= mb.build_code_creator( module_name='SmpSim' ) # This is an attempt at getting the bases included for Vehicle baseModel = mb.class_('Model') print type(mb.code_creator) baseModel_creators = code_creators.creator_finder.find_by_declaration( lambda decl: decl is baseModel, mb.code_creator, False ) vehicle = mb.class_('Vehicle') # This is the class I need to add the bases to vehicle = ( code_creators.class_t, code_creators.class_wrapper_t ) baseModel_creators = filter( lambda c: isinstance(c, vehicle), baseModel_creators) for c in baseModel_creators: c.create = lambda: '' <<End Snippet================================================================= and I get the following error: Traceback (most recent call last): File "/data/home/scott/eclipse/Smp_lib/generate_code.py", line 157, in <module> baseModel_creators = code_creators.creator_finder.find_by_declaration( lambda decl: decl is baseModel, mb.code_creator, False ) File "/data/apps/oss/lib/python/pyplusplus/code_creators/algorithm.py", line 87, in find_by_declaration , search_area ) TypeError: 'module_t' object is not iterable I'm sure this is something I'm doing wrong, but I looked at the API's and could not figure it out. Does anyone have an idea what I'm doing wrong here? Thanks in advance for any help. Scott
|
|
|
Re: Base class defined in other header file not includedin bp::bases<>On Sun, Sep 7, 2008 at 12:48 AM, Rocketman@JSC <snemeth@...> wrote:
> Roman Yakovenko wrote: >> >> On 7/13/06, Haridev, Meghana <mharidev@...> wrote: >>> In other words, I want the generated code to look like this: >>> /* bp::class_< baseB >( "baseB" ); - Do not want to generate */ >>> >>> bp::class_< baseA >( "baseA" ); >>> >>> bp::class_< derivedC, bp::bases< baseA, baseB > >( "derivedC" ); Did you read the following document http://language-binding.net/pyplusplus/documentation/multi_module_development.html ? I think, it will give you easy and clear way to achieve what you want. HTH -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ _______________________________________________ C++-sig mailing list C++-sig@... http://mail.python.org/mailman/listinfo/c++-sig |
| Free Forum Powered by Nabble | Forum Help |