Hi Alex,

That would be awesome, if it's not too much trouble..

well, void* is trouble by definition, but it has to be dealt with. Doing
something with it, is actually not that hard, but getting it consistent is.

Some code is in, on the reflex-support branch (to be merged once it is
documented): void* is represented as an array (I didn't see a PyCObject or
PyCapsule outside of cpyext), both for returns and data members. There is
a special case cppyy.gbl.nullptr (C++11 style), which is a unique object to
represent NULL.

ATM, both int(0) and None can also be used in place of nullptr, but the next
step will be to remove that (None is void, not NULL; and 0 is archaic). Is
also just a matter of being consistent.

addressof() has been changed to accept an array, to return its start address
as an integer; bind_object() can take both the result of addressof() as well
as the array directly.

but there are some other places
in the library where void pointers are passed around (for example,
assigning "user data" to some types of objects), which I've been trying to
figure out how I would deal with if I couldn't use "void*", so it would
definitely be useful..

Passing C++ instances through void* was already supported, and so that should
be fine. There was an issue if the code started out with a void* (e.g. from
a function call), but that now works as well. (That consistency thing again.)

Currently, for the callbacks, I'm converting the C++ object pointer to an
intptr_t, and then on the Python side using cppyy.bind_object to convert
that intptr_t back to an object of the specified type.  I've noticed,
however, that if I (for example) call a function which returns an object of
BaseClass, but the object being returned actually happens to be a
DerivedClass object, cppyy (somehow) figures this out and it comes through
as a DerivedClass automatically in Python (so you don't need to cast it).

Yes, this is based on C++'s (limited) RTTI: the dictionary stores class info
both by (human readable) class name as well as by typeid. A pre-compiled (or
generated, in the case of Cling) cast function to calculate the offset does
the rest. (And if the inheritance is non-virtual, the JIT will elide all of
that machinery.)

Is there some way I could do something like bind_object, but have it do the
automagical "figure out what derived class this actually is and return that
instead" behavior that cppyy can apparently do in other places?

I've added a parameter 'cast' which can be set to True. Note that the call
to bind_object already takes another boolean parameter, owns, so better use
keyword args. Note that the class name and the pointer value still have to
match (was already true before).

There is one more caveat: if a void* pointer was first bound to a base
class, and is later bound to a derived class (or vice versa), the memory
regulator will not work, so any existing python object will not be reused.

Best regards,
           Wim
--
wlavrij...@lbl.gov    --    +1 (510) 486 6411    --    www.lavrijsen.net
_______________________________________________
pypy-dev mailing list
pypy-dev@python.org
https://mail.python.org/mailman/listinfo/pypy-dev

Reply via email to