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

Gustavo Carneiro gjcarneiro at gmail.com
Fri Jun 5 19:00:55 CEST 2009


2009/6/5 J. Michael Owen <mikeowen at llnl.gov>

> Hi Taner,
> Thanks for the suggestion!  I actually was trying the same solution, except
> I wasn't sure how to handle the iterators.  I'll try it out as you do in
> your example -- are you able to iterate over the vector in python the usual
> way?  As in "for x in vec:"?
>
> Two curious things I noted about wrapping "std::vector" myself:
>
> 1.  I can't seem to get indexing access to work, even though I wrap an
> indexing operation with the python name "__getitem__"
>
> 2.  I also can't get python's len function to work, even if I provide
> "__len__" as follows:
> veci.add_method("size", "int", [], custom_name="__len__")
>
> Have you been able to make either of those methods work?
>

It won't work because those are special methods in C/C++ side; Python
extension types use a "slots" mechanism for this kind of thing, see
http://www.python.org/doc/2.6/c-api/typeobj.html


>
> Thanks!
>
> Mike.
>
> On Jun 4, 2009, at 11:42 PM, Taner Yildirim wrote:
>
> 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:
>
>
> 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/08fd4988/attachment-0001.htm>


More information about the Cplusplus-sig mailing list