QByteArray转换和指针转换

时间:2016-02-04 16:42:24

标签: c++ qt casting qbytearray

我正在使用Qt和C ++。我必须管理电子板的错误代码。我可以以QByteArray的形式获得这些错误,我必须转换为QVariant。我没有找到任何实用的方法来做这个(所以如果你有一个我在这里听)。无论如何,试图将它(QByteArray)转换为QVariant,我找到的唯一方法是使用像这样的代码这样:

QByteArray value;     //This is the QByteArray where I have the error code
QVariant qVariantOut; //This is the QVariant where I want to put the error
qVariantOut = QVariant(*(quint64*)(void*)(&(value).data()[0]));

由于我使用的铸造步骤不好,我偶然发现了各种好的铸造规则,我做了一些像这样的事情:

qVariantOut =  QVariant(*(static_cast<quint64*(static_cast<void*>((&(value).data()[0]))));

这些演员似乎有效,所以我决定加深演员主题,但我不理解我得到的一些结果。以下我介绍了我尝试过的所有案例。如果有人可以给我一个解释(我将会介绍我的)每个案例中发生的事情,那就太棒了。

  1. qVariantOut = QVariant(*((quint64 *)value.data())); 我认为这是有效的,因为value.data()返回一个char *,而cast quint64 *执行reinterpret_cast(如果我很好地解释了它在这里所说的内容:When should static_cast, dynamic_cast, const_cast and reinterpret_cast be used?)。这个理由是对的吗?

  2. qVariantOut = QVariant(*(static_cast<quint64*>(value.data()) )); 这个工作不起作用,因为我试图直接对一个quint64 *进行static_cast。但在这里我有一个问题:为什么不能从char *转换为quint64 *。 Aren是否有一些必须使用static_cast的基础(POD)类型?

  3. 我想更好地理解这些演员...我甚至找到了一个人说:&#34;如果你需要投射指针,通过void *&#34;投射它们。评论

    1. qVariantOut = QVariant( (quint64*)(value.data()) ); 这有点像奖金。我尝试使用此代码将QVariant放入指针...这给了我错误&#34; QVariant :: QVariant(void )在此上下文中是私有的* &#34;我不知道这意味着什么。
    2. 谢谢。

      编辑:对于表示可能是XY问题的用户。以下是一些更多信息。我写了一个函数来从电子板上获取变量。这些变量可以是QString,quint64,qint32,quint8等......在我的函数中,为了获得这些变量,我使用了一个外部函数(来自外部库,由内部开发)我公司的电子部门,我必须使用它但不能修改它)。为了使用这个外部函数,我需要传递参数:我想要读取的变量(即:错误,警告,温度,固件版本......),输出QByteArray以及我想要读取的变量的大小(例如,error-&gt; sizeof(quint64),temperature-&gt; sizeof(quint8))。如您所知,此外部函数返回QByteArray。

      我使用强制转换为quint64呈现代码的事实只是我的函数的一个例子。

      我想将此QByteArray转换为QVariant,因此我的函数可以返回此qVariantOut,我将转换为正确的变量(例如:我知道我需要读取错误变量我调用我的函数来设置变量大小并将其传递给将返回QByteArray的外部函数(连同变量名)。这个QByteArray将在我的函数外部返回的QVariant中转换。外部我将转换为QVariant到正确的变量,例如使用QVariant方法的错误的quint64)。请注意我这样做是因为系统的约束(我需要使用外部函数,它总是为我想要读取的每种类型的变量返回QByteArray)因为我没有找到一个更好更实用的方法将QByteArray转换为最终变量(例如:如果我使用qba.toLongLong qba a QByteArray ,它没有用)...如果你有一个,正如我之前所说,我在这里听你说。

      无论如何,我不想过多关注XY问题(但如果是XY问题我想明白解决它)但我想更好地理解投射规则并进行建设性的讨论我的疑问和问题:))

1 个答案:

答案 0 :(得分:1)

根据您的更新,这并不像第一眼看上去那么疯狂。你有一个内部API将随机变量放入QByteArray而不是像QVariant这样的东西正是它的制作方式,这有点疯狂,但我知道你已经被你所拥有的东西所困扰。

您有两种选择:

  1. 演员,但没有必要做任何复杂的事情,只需使用reinterpret_cast。使用void*投射到static_cast然后返回其他内容与reinterpret_cast相同,所以您也可以先致电reinterpret_cast

  2. memcpy(&target, byteArray.data(), sizeof(target));这可以避免施法,但几乎同样难看。从理论上讲,考虑到内存对齐问题,它会更加安全(不必依赖QByteArray中的数据与reinterpret_cast正确对齐)。它还可以让您随时掌握数据,而不会让QByteArray中的内部指针在您背后回收。

  3. 请注意,这两个选项仅适用于POD类型,但我认为除了QString以外的其他所有内容都是,并且对于QString,您必须根据编码做出特殊情况(非常简单,如果是ASCII / Latin1)。

    至于为什么你不能直接从char *到quint64 *进行static_cast,这不是一个static_cast。您不能在不同类型之间进行静态转换,只能在相关类型之间进行静态转换,例如base *和从base派生的类之间。这个answer by EdChum中有一个很好的解释static_cast的有限用例。