[C++-sig] pybindgen: Why do wrapped C++ containers not look more like python containers?

Gustavo Carneiro gjcarneiro at gmail.com
Fri Jun 5 18:57:41 CEST 2009


2009/6/5 Taner Yildirim <taner at seas.upenn.edu>

>  Dear  Mike,
>
>
>
> Concerning your question about add_method for stl_vector, I was able to add
>
>
> almost all standard methods of std_vector by simply wrapping the
> std::vector without
>
> even using the mod.add_container!! Since I am very new to pybindgen,
>
> I am not sure if there is anything wrong with this approach but it seems to
> work quite well.
>
> Hopefully  Gustava can comment on this more:
>
>
>
I think it is wonderful that you could get it to work without
add_container.  Nothing like discovering a tool you develop is being used in
new and interesting ways :-)

There are advantages and disadvantages to your method.  On the plus side,
you can wrap normal container methods, and have a more rich container with
lots of methods.  On the other hand, normal C++ classes do not support the
iteration protocol (tp_iter), and is more work than should be needed to
support this (having to declare the iterator type as well...).  Also, with
add_container, parameters of that type will accept also python lists in lieu
of the container type itself.

One possible solution that I might try implementing some day is to converge
the two solutions, i.e., give iteration powers to normal C++ classes.  But
at the time I thought it was not very simple to do, and I opted to
completely separate the two types.


>
> In summary, here’s how I get the std::vector<int> work in python
>
> using pybindgen without  add_container:
>
>
>
> >>>>>>>>> THIS is the header file:   tst1.h  <<<<<<<<<
>
>
>
> #include<vector>
>
> #include <iostream>
>
> typedef std::vector<int> VecI;
>
> typedef std::vector<int>::iterator Iter_VecI;
>
> #here you can do typdef for other types like double, string, etc
>
> >>>>>>> END OF THE HEADER FILE   <<<<<<<<<<<<<<<<<<<<
>
>
>
>
>
> And here's the pybind-gen code to generate the wrapper.cpp
>
>
>
> >>>>>>>>>>>>>>   wrap.py <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
>
>
>
> import sys,pybindgen
>
> from pybindgen import ReturnValue, Parameter, Module, Function,
> FileCodeSink
>
>
>
> def my_module_gen(file_out):
>
>         mod=Module('tst1')
>
>         mod.add_include('"tst1.h"')
>
>         iter_veci=mod.add_class('Iter_VecI')
>
> #
>
>         veci=mod.add_class('VecI')
>
>         veci.add_constructor([])
>
>
> veci.add_constructor([Parameter.new('int','size'),Parameter.new('int','val'
> )])
>
>         veci.add_constructor([Parameter.new('VecI','vec_int')])
>
>         veci.add_method('begin','Iter_VecI',[])
>
>         veci.add_method('end','Iter_VecI',[])
>
>
> veci.add_constructor([Parameter.new('Iter_VecI','begin'),Parameter.new('Iter_VecI','end')])
>
>         veci.add_method('push_back','void',[Parameter.new('int','value')])
>
>         veci.add_method('size',ReturnValue.new('int'),[])
>
>         veci.add_method('pop_back','void',[])
>
>
> veci.add_method('at',ReturnValue.new('int'),[Parameter.new('int','index')])
>
>         veci.add_method('front',ReturnValue.new('int'),[])
>
>         veci.add_method('back',ReturnValue.new('int'),[])
>
>         veci.add_method('clear','void',[])
>
>         veci.add_method('empty',ReturnValue.new('bool'),[],is_const=True)
>
>         veci.add_binary_comparison_operator('==')
>
>         mod.generate(file_out)
>
>
>
> my_module_gen(sys.stdout)
>
>
>
> >>>>>>>>>>>  END OF THE WRAPPER CODE <<<<<<<<<<<<<<<<<<<<<<<<<<<<<
>
>
>
> Here’s a simple shell script to generate the code
>
> (I generate pyd since I work in mingw envirentment):
>
>
>
> >>>>>>>>>  simple shell script to generate the library <<<<<<<<<
>
> rm tst1.pyd wrap.cpp
>
> python wrap.py  > wrap.cpp
>
> g++ -c wrap.cpp -IC:/Python25/include
>
> g++ -shared -o tst1.pyd wrap.o -LC:/Python25/libs -lpython25
>
> #
>
> >>>>>>>>>>>  end of the script <<<<<<<<<<
>
>
>
> Here’s the usage of the tst1.pyd in python:
>
>
>
> >>> from tst1 import *
>
> >>> dir()
>
> ['Iter_VecI', 'VecI', '__builtins__', '__doc__', '__name__']
>
> >>> a=VecI()   # default constructor
>
> >>> a.size()   # check the size
>
> 0
>
> >>> a.push_back(2)  # add an entry
>
> >>> a.size()
>
> 1
>
> >>> a.at(0)  # get the value at entry index 0
>
> 2
>
> >>> a.push_back(2)
>
> >>> a.push_back(3)
>
> >>> a.size()
>
> 3
>
> >>> b=VecI(a.begin(),a.end())  #constructor using iterator
>
> >>> b.size()
>
> 3
>
> >>> a==b  # check if they are the same
>
> True
>
> >>> b.push_back(1)
>
> >>> b.size()
>
> 4
>
> >>> a==b
>
> False
>
> >>> b.clear()
>
> >>> b=VecI(4,10)  # constructor for 4 entry with value of 10
>
> >>>
>
> >>> c=VecI(a) #contructor from an other vector
>
> >>> c==a
>
> True
>
> >>> c.pop_back()
>
> >>> c==a
>
> False
>
> >>> a.empty()
>
> False
>
> >>> a.clear()
>
> >>> a.empty()
>
> True
>
> >>>
>
> >>>>>>>>>>>  SOME COMMENTS <<<<<<<<<<<<<<<<<<<<<<<<<
>
>
>
> Needless to say, one can simple change the type “int” in the wrapper code
> to double, float, etc and everything works for that type. Ideally, I would
> like to have this sort of wrapper header file included in pybindgen for a
> generic type TTTT and then we can simply specify what type TTT we want (like
> TTT=[‘int’,’float’, ‘string’]) and then pybindgen could just automatically
> generate the each template with the requested type in the wrapper code!!!
> Anyway, this would be my solution until the pybindgen container will have
> all the standards methods implemented!!!
>
>
>
> QUESTION: In this approach, Is it possible to add a custom constructor (in
> the python end)
>
> such as a=VecI([a python list of integer])??? And how do I get a python
> list from my VecI object using list??
>
> I guess implementing these two things are not easy and probably that’s why
> we have the
>
> pybindgen-container module at first place!!!
>
>
>
> Anyway, hope what I wrote above is not a total non-sense (which is quite
> possible considering I have only a week experience wit pybindgen!!!).
>
>
>
> Best regards
>
> Taner
>
>
>
>
> ********************************************************************************
>
> Dr. Taner Yildirim, Ph.D. Physicist,
>
> Adjunct Associate Professor,
>
> Materials Science and Engineering,
>
> University of Pennsylvania
>
> and
>
> Computational and Neutron Science Team Leader,
>
> NIST Center for Neutron Research,
>
> National Institute of Standards and Technology,
>
> 100 Bureau Drive, Gaithersburg, MD 20899-6100.
>
> Email: taner at nist.gov or taner at seas.upenn.edu
>
> PHONE: 301-975-6228 FAX : 301-921-9847
>
> Web : http://webster.ncnr.nist.gov/staff/taner
>
>
> ********************************************************************************
>
>
>



-- 
Gustavo J. A. M. Carneiro
INESC Porto, Telecommunications and Multimedia Unit
"The universe is always one step beyond logic." -- Frank Herbert
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/cplusplus-sig/attachments/20090605/cc354e88/attachment-0001.htm>


More information about the Cplusplus-sig mailing list