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