2009/6/7 Taner Yildirim <[email protected]>
> 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
[email protected]
http://mail.python.org/mailman/listinfo/cplusplus-sig