1
votes

It seems like something is going wrong when pointer values transcend between C++ and QML world. I am using the plain old fromValue() and value() to convert to and from void *, and it does work as expected as long as the variant stays on the C++ side.

The moment it is returned to QML, it now resolves to null, and when passed back to C++, the variant type is changed from void * to std::nullptr_t and the value is null.

returning 0x3ba5b10 // created
converting to qvariant 0x3ba5b10 // converting
converted QVariant(void*, 0x3ba5b10) 0x3ba5b10 // now variant, testing value() - all good
qml: null // in qml
received QVariant(std::nullptr_t, (nullptr)) 0x0 // back in c++

I am using:

Q_DECLARE_METATYPE(void*)
qRegisterMetaType<void*>();

Any clue as to what is going on here?

Edit: it keeps even more strange, I get it to work by casting the pointer values to 64 bit uint and back, but upon the transition to QML, the type info gets messed up, in C++ the variant is of type qulonglong, arriving back from QML it is now a double, hence the suspicion it might round something and mess up the pointer value.

Edit 2: note that the question is not about recommending practices but about why this doesn't work as expected and observed prior to reaching QML.

2
Could you provide minimal working example, please? - tro
Why are you registering void* in the type-system? It is already there: QMetaType::VoidStar 31 void * (from enum QMetaType::Type) - user6556709
@user6556709 yes I am aware of that, but just in case, and because QVariant didn't have it as part of the API. It doesn't make a difference. - dtech
For your edit: Have you unpacked/repacked it trough JS? If so: JS doesn't have integer datatypes. All numbers are doubles. - user6556709

2 Answers

3
votes

You don't need to register void*, rather use the metatype QMetaType::VoidStar.

Note that to register the metatype SomeCustomType*, you need to use an alias.

using SomeCustomTypePtr = SomeCustomType*;
Q_DECLARE_METATYPE(SomeCustomTypePtr)
qRegisterMetaType<SomeCustomTypePtr>();
1
votes

Isn't even possible to do such declarations?

According to official documentation on Q_DECLARE_METATYPE(Type):

This macro makes the type Type known to QMetaType as long as it provides a public default constructor, a public copy constructor and a public destructor. It is needed to use the type Type as a custom type in QVariant.

This macro requires that Type is a fully defined type at the point where it is used.

Sounds strange that this works at least in C++ part.

Don't you think that it will be better and straight-forward solution to declare your type pointer instead of void*?