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?
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: ta...@nist.gov or ta...@seas.upenn.edu
PHONE: 301-975-6228 FAX : 301-921-9847
Web : http:// webster.ncnr.nist.gov/staff/taner
********************************************************************************
_______________________________________________
Cplusplus-sig mailing list
Cplusplus-sig@python.org
http://mail.python.org/mailman/listinfo/cplusplus-sig