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

Reply via email to