1

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.

dtech
  • 47,916
  • 17
  • 112
  • 190
  • Could you provide minimal working example, please? – NG_ May 16 '19 at 11:43
  • Why are you registering void* in the type-system? It is already there: QMetaType::VoidStar 31 void * (from [enum QMetaType::Type](https://doc.qt.io/qt-5/qmetatype.html#Type-enum)) – user6556709 May 16 '19 at 11:48
  • @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 May 16 '19 at 11:49
  • For your edit: Have you unpacked/repacked it trough JS? If so: JS doesn't have integer datatypes. All numbers are doubles. – user6556709 May 16 '19 at 12:58

2 Answers2

3

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>();
UmNyobe
  • 22,539
  • 9
  • 61
  • 90
1

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*?

Community
  • 1
  • 1
NG_
  • 6,895
  • 7
  • 45
  • 67
  • There is no type information available here. The runtime is supposed to know what it is. A pointer is essentially just an unsigned integer, so I don't think I am expecting too much when I expect this to work. – dtech May 16 '19 at 11:42
  • 1
    But what's the use in QML than? If you really want it in QML, I would write a wrapper class and register that actually – Amfasis May 16 '19 at 11:43
  • @Amfasis the pointer value is not used in QML, it just has to be selected from there and passed back to C++. – dtech May 16 '19 at 11:46
  • @dtech, so the user should select a hex-number or something? To me it sounds like a bit of weird view/model design – Amfasis May 16 '19 at 12:24