8

My project consists of an app that links to two static libraries. Each of the libraries declares Q_DECLARE_METATYPE< QUuid >, in order to use QUuid with QVariant, which leads to a 'redefinition of struct QMetaTypeId< QUuid >' error.

What is the correct way to go about this while keeping the ability to use each library on its own in different projects?

leemes
  • 44,967
  • 21
  • 135
  • 183
szayat
  • 408
  • 3
  • 9
  • 1
    I don't understand why you didn't get "redefinition of struct 'QUuid'". Only the author of "QUuid" should declare that metatype id. Otherwise it's only a question of time until you run into this problem. – Johannes Schaub - litb Jun 30 '12 at 11:06
  • @JohannesSchaub-litb QUuid is declared in Qt headers. I don't have control over that code, but I still want to use that type in QVariant. – szayat Jul 03 '12 at 15:43

1 Answers1

4

As a workaround you can call the Q_DECLARE_METATYPE macro from the implementation files that need it instead of calling it from the header files, or as the documentation suggests, call it from private headers in each library.

But because QUuid stores its content as a QByteArray which is already supported by QVariant, you don't need to use Q_DECLARE_METATYPE to do that (from Qt 4.8 only):

// QVariant variant;
// QUuid uuid;
variant = uuid.toByteArray();
uuid = variant.toByteArray();

or the same thing, but a little less efficiently, with QString (before Qt 4.8):

variant = uuid.toString();
uuid = variant.toString();

And since QVariant will implicitly convert between QString and QByteArray, you can mix toString and toByteArray without any problem.

alexisdm
  • 29,448
  • 6
  • 64
  • 99
  • What is the exact criteria for implementation files that need `Q_DECLARE_METATYPE`? I added it to all files that set/get QUuid in/from a QVariant, as well as all files that inspect QVariant type name and act on it. Things seem to work, no compile errors, and all data seems to be read/written correctly. Can I rely on the lack of compile errors to be sure Q_DECLARE_METATYPE is correctly declared whenever it's needed? In theory, could there be silent failures in getting/setting QVariant values because of these modifications? – szayat Jul 03 '12 at 15:35
  • Note that I can't use the `QString` or `QByteArray` approach, since in a lot of parts of my code I don't know in advance that I'm expecting a `QUuid`. I need `QVariant` to be able to identify the stored value as `QUuid`. – szayat Jul 03 '12 at 15:41
  • @szayat As long as you only use `QUuid` with `QVariant`, if it compiles, you won't have any warning later at runtime. You would only get warnings if you were using `QUuid` as a parameter in a queued signal/slot connection or `invokeMethod` before calling `qRegisterMetaType`, or if you wanted to serialize the `QVariant` containing the `QUuid` on a `QDataStream` without calling `qRegisterMetaTypeStreamOperators`. – alexisdm Jul 03 '12 at 16:57