PDA

View Full Version : Problem with QVariant and stream operators after upgrade



Kwakkie
2nd May 2016, 14:10
Hi all

We've been using Qt 4.8.x for some time now. But now we want to upgrade to 5.5.1. Part of our application is using QGeoCoordinate. In 4.8, this was part of the QtMobility namespace. Of course, in 5.5.1 this is now part of the positioning module.

Our application saves the QtMobility::QGeoCoordinate information to a file using a stream, and was able to read it back in. For this, we had these in our code to be able to use the stream and put the QGeoCoordinate in a QVariant.


Q_DECLARE_METATYPE(QtMobility::QGeoCoordinate);
qRegisterMetaType<QtMobility::QGeoCoordinate>("QtMobility::QGeoCoordinate");
qRegisterMetaTypeStreamOperators<QtMobility::QGeoCoordinate>("QtMobility::QGeoCoordinate");

So now that QtMobility::QGeoCoordinate changed to the proper QGeoCoordinate, the loading of old streamed files results in:

"Trying to construct an instance of an invalid type, type id: 127
QVariant::load: unable to load type 42."
And eventually a crash.

Is there any way to solve this? I tried declaring the metatype and streaming metatype to something like

qRegisterMetaType<QGeoCoordinate>("QtMobility::QGeoCoordinate");
qRegisterMetaTypeStreamOperators<QGeoCoordinate>("QtMobility::QGeoCoordinate");

And other things, but nothing seems to work.

Added after 1 5 minutes:

Thinking about this, what about all custom classes with serialization that contain QGeoCoordinate? How will these be handled? I have lots of these, each declared and registered... How will the QVariant metatypes be handled?

Kwakkie
3rd May 2016, 16:29
No ideas so far?

anda_skoa
3rd May 2016, 17:28
Are you trying to deserialize a stream that has been serialized with the old type?

Cheers,
_

Kwakkie
3rd May 2016, 18:04
Yes, that is correct.

I also tried adding the old type back in so I can deserialize it back and "convert" to the new type, but the mobility dll requires qt4core and qt4gui. So that doesn't work well if you're using qt5 as well.

d_stranz
3rd May 2016, 20:35
A shot in the dark here: would QMetaType::registerConverter() help? The documentation is a bit sparse, but it sounds like what you are trying to get to happen.

Kwakkie
4th May 2016, 08:33
Been reading up on registerConverter(). As far as I can see, you need to supply the conversion function. That makes a lot of sense of course, but it is basically registering a converter instead of e.g. in-lining it at the load code. It still means I'd need the original dll containing the type, the dll being unavailable as it's qt4.

anda_skoa
4th May 2016, 09:29
I don't know the details of how the type registration works but since this is done at runtime I doubt that even the old type would be registered with the old code.
But in case it would, you could forward port it.

However, my guess is that the typeIds are handed out linearly, so if the new type system doesn't have 126 types yet by the time your type is registered, it just won't get 127 as its id.

You could, however, try registering the new type and then using QMetaType::registerTypedef() to make it an alias for 127.

Cheers,
_