2009/6/7 Taner Yildirim <ta...@seas.upenn.edu> > Dear Mike, > > > > I noticed that the special function __call__ works in pybindgen. When I use > the custom_name as __call__, then I can get the vector as (i)! > > In cppclass.py, the program checks if the name== __call__ to treat this > case specially and then converts it into slots! I suppose, you can do the > similar thing for the tp_len, tp_iter and tp_iternext! Then, these functions > can be controlled by the user easily. I think this is also standard in > python!! > > > > For example, if I create a simple class: > > > > class b: > > def __getitem__(self,i): > > return i > > def __len__(self): > > return 100 > > > > then in python, you can do the iteration and len as follow: > > > > a=b() > > for i in a: print i > > len(a) > > > > In short, I think pybindgen should also allow user to overload these > special functions easily for class. Since it is already done for __call__, > why not do it for others, in particular for tp_iter and tp_iternext. Then > the user can create his/her own class with custom special functions easily! > > > > Gustavo: Do you think this is doable easily in pybindgen??? My > understanding is that the only thing that I need is to replace the “NONE” > with my function name for the given tp_slot in the generated wrapper code!! > Is this correct or there is more to it!!! > It has to be checked case-by-case. tp_iter maybe can be supported generically, however tp_iternext is more complicated, and I don't think you can assign an arbitrary C++ method/function to it. Especially if you wan the generated code to be efficient. It needs to check the C++ iterator, see if it has reached container.end(), and raise StopIteration if so. There is no generic C++ code that can do it. Python and C++ are just too different in this respect.
tp_call was easy because the slot expects a C function that is the same thing as a normal python method wrapper. But not all slots expect this signature, some are very specific. > Back to my toy std:vector<int> class-wrapper that I send in the previous > email, I found out why the access with the pointer is too slow! > > I had defined a get_function: > > > > int get(VecI vec, Iter_VecI it) { return *it; } > > > > which allows me to get the value of container using the iterator. However > in this function, the first parameter is the huge-array! Hence to get a > value, I was passing the whole array into the function!! I had done this in > this way, because the add_function_as_method expects the first parameter to > be the class type (i.e. VecI). > In tests/foomodulegen.py: ## add a function that appears as a method of an object SomeObject.add_function_as_method('some_object_get_something_prefixed', ReturnValue.new('std::string'), [Parameter.new('const SomeObject*', 'obj', transfer_ownership=False), Parameter.new('std::string', 'something')], custom_name='get_something_prefixed') This means that the function/method will take a pointer as first parameter, not a value, thus avoiding the value copy performance penalty. Maybe this is what you want? If you do not like pointers you can also try references. > Since in c++, we get the value of container by simply *iterator, I thought > we should do the same thing here. > > Therefore, I now modified the get_function as > > > > int get (Iter_VecI it) {return *it;} > > > > and put this function to iter_class as method with custom name “val” and > also with “__call__”. > > > > Hence now I can iterate over the vector-items as > > Iter=vi.begin() > > While (iter != vi.end()): > > Item_value = it() # thanks to to __call__ slot! > > Item_value = it.val() # maybe this is better notation!! > > > > Anyway, now the sum_test in the previous email takes about the same time as > the indexing! > > > > I am still not able to add_function_as_constructor (for my FromList > function)? Unfortunatley, pybindgen expects pointer-function for this. Then > I do not know how to construct my vector without returning it!!! Any > suggestion would be appreciated very much! > add_function_as_constructor expects a function that returns the object. Usually the return value is like ReturnValue("MyObject*", caller_owns_return=True), so that the object is constructed only once and owership is passed to the python wrapper. Maybe I do not quite understand you problem. > I do not see why the add_function_as_method has a different convention than > as add_function_as_contructor??? In any case, from above get_function > example, I learned that add_function_as_method is not a good thing if the > first-parameter requires a huge data passing to the function!! Probably I am > using add_function_as_method incorrectly! I’ll have to look at more in > foomodegenerate.py which is my main source for learning the pybindgen. As a > fortran user over 20 years, this c++ pointers, references, etc are all very > confusion to me!!! > > > A final question: Can’t we make the container-class inherited from > cppclass???? If this is easy to do, then we can add all the methods that > std:container support easily as done in my toy std-int class wrapper! > I am beginning to think this is a good idea. I added a bug report for this, though I can give no guarantees when I will handle it: https://bugs.launchpad.net/pybindgen/+bug/384488 Regards, -- Gustavo J. A. M. Carneiro INESC Porto, Telecommunications and Multimedia Unit "The universe is always one step beyond logic." -- Frank Herbert
_______________________________________________ Cplusplus-sig mailing list Cplusplus-sig@python.org http://mail.python.org/mailman/listinfo/cplusplus-sig