<br><br><div class="gmail_quote">2009/6/5 Taner Yildirim <span dir="ltr"><<a href="mailto:taner@seas.upenn.edu">taner@seas.upenn.edu</a>></span><br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
<div link="blue" vlink="purple" lang="EN-US">
<div>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">Dear Mike,</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;"> </span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">Concerning your question about add_method for stl_vector, I was able to
add </span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">almost all standard methods of std_vector by simply wrapping the
std::vector without</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">even using the mod.add_container!! Since I am very new to pybindgen, </span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">I am not sure if there is anything wrong with this approach but it
seems to work quite well.</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">Hopefully Gustava can comment on this more:</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;"> </span></font></p></div></div></blockquote><div>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 :-)<br>
<br>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.<br>
<br>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.<br>
<br></div><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;"><div link="blue" vlink="purple" lang="EN-US"><div><p><font size="2" face="Courier New"><span style="font-size: 10pt;"></span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;"> </span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">In summary, here’s how I get the std::vector<int> work in
python </span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">using pybindgen without add_container:</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;"> </span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">>>>>>>>>> THIS is the header
file: tst1.h <<<<<<<<<</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;"> </span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">#include<vector></span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">#include <iostream></span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">typedef std::vector<int> VecI;</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;" lang="SV">typedef std::vector<int>::iterator Iter_VecI;</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">#here you can do typdef for other types like double, string, etc</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">>>>>>>> END OF THE HEADER FILE
<<<<<<<<<<<<<<<<<<<<</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;"> </span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;"> </span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">And here's the pybind-gen code to generate the wrapper.cpp</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;"> </span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">>>>>>>>>>>>>>>
wrap.py
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;"> </span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">import sys,pybindgen</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">from pybindgen import ReturnValue, Parameter, Module, Function,
FileCodeSink</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;"> </span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">def my_module_gen(file_out):</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;"> mod=Module('tst1')</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">
mod.add_include('"tst1.h"')</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">
iter_veci=mod.add_class('Iter_VecI')</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">#</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;"> veci=mod.add_class('VecI')</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;"> veci.add_constructor([])</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">
veci.add_constructor([Parameter.new('int','size'),Parameter.new('int','val' )])</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">
veci.add_constructor([Parameter.new('VecI','vec_int')])</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">
veci.add_method('begin','Iter_VecI',[])</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">
veci.add_method('end','Iter_VecI',[])</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">
veci.add_constructor([Parameter.new('Iter_VecI','begin'),Parameter.new('Iter_VecI','end')])</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">
veci.add_method('push_back','void',[Parameter.new('int','value')])</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">
veci.add_method('size',ReturnValue.new('int'),[])</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;"> veci.add_method('pop_back','void',[])</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">
veci.add_method('at',ReturnValue.new('int'),[Parameter.new('int','index')])</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">
veci.add_method('front',ReturnValue.new('int'),[])</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">
veci.add_method('back',ReturnValue.new('int'),[])</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;"> veci.add_method('clear','void',[])</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">
veci.add_method('empty',ReturnValue.new('bool'),[],is_const=True)</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">
veci.add_binary_comparison_operator('==')</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;"> mod.generate(file_out)</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;"> </span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">my_module_gen(sys.stdout)</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;"> </span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">>>>>>>>>>>> END OF THE WRAPPER
CODE
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;"> </span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">Here’s a simple shell script to generate the code </span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">(I generate pyd since I work in mingw envirentment):</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;"> </span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">>>>>>>>>> simple shell script to
generate the library <<<<<<<<<</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">rm tst1.pyd wrap.cpp</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">python wrap.py > wrap.cpp</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">g++ -c wrap.cpp -IC:/Python25/include</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">g++ -shared -o tst1.pyd wrap.o -LC:/Python25/libs -lpython25</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">#</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">>>>>>>>>>>> end of the script
<<<<<<<<<<</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;"> </span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">Here’s the usage of the tst1.pyd in python:</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;"> </span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">>>> from tst1 import *</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">>>> dir()</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">['Iter_VecI', 'VecI', '__builtins__', '__doc__', '__name__']</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">>>> a=VecI() # default constructor</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">>>> a.size() # check the size</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">0</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">>>> a.push_back(2) # add an entry</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">>>> a.size()</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">1</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">>>> <a href="http://a.at" target="_blank">a.at</a>(0) # get the value at entry index 0</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">2</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">>>> a.push_back(2)</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">>>> a.push_back(3)</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">>>> a.size()</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">3</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">>>> b=VecI(a.begin(),a.end()) #constructor using
iterator </span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">>>> b.size()</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">3</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">>>> a==b # check if they are the same</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">True</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">>>> b.push_back(1)</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">>>> b.size()</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">4</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">>>> a==b</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">False</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">>>> b.clear()</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">>>> b=VecI(4,10) # constructor for 4 entry with value of
10</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">>>> </span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">>>> c=VecI(a) #contructor from an other vector</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">>>> c==a</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">True</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">>>> c.pop_back()</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">>>> c==a</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">False</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">>>> a.empty()</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">False</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">>>> a.clear()</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">>>> a.empty()</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">True</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">>>> </span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">>>>>>>>>>>> SOME COMMENTS
<<<<<<<<<<<<<<<<<<<<<<<<<</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;"> </span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">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!!!</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;"> </span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">QUESTION: In this approach, Is it possible to add a custom constructor (in
the python end) </span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">such as a=VecI([a python list of integer])??? And how do I get a python
list from my VecI object using list??</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">I guess implementing these two things are not easy and probably that’s
why we have the</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">pybindgen-container module at first place!!!</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;"> </span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">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!!!). </span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;"> </span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">Best regards</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">Taner</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;"> </span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">********************************************************************************</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">Dr. Taner Yildirim, Ph.D. Physicist, </span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">Adjunct Associate Professor,</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">Materials Science and Engineering,</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">University</span></font>
of Pennsylvania</p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">and </span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">Computational and Neutron Science Team Leader,</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">NIST</span></font>
Center for Neutron
Research, </p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">National Institute
of Standards and
Technology, </span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">100 Bureau Drive</span></font>,
Gaithersburg, MD
20899-6100. </p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">Email: <a href="mailto:taner@nist.gov" target="_blank">taner@nist.gov</a> or <a href="mailto:taner@seas.upenn.edu" target="_blank">taner@seas.upenn.edu</a> </span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">PHONE: 301-975-6228 FAX : 301-921-9847 </span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">Web : <a href="http://webster.ncnr.nist.gov/staff/taner" target="_blank">http://webster.ncnr.nist.gov/staff/taner</a> </span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;">********************************************************************************</span></font></p>
<p><font size="2" face="Courier New"><span style="font-size: 10pt;"> </span></font></p>
</div>
</div>
</blockquote></div><br><br clear="all"><br>-- <br>Gustavo J. A. M. Carneiro<br>INESC Porto, Telecommunications and Multimedia Unit<br>"The universe is always one step beyond logic." -- Frank Herbert<br>