【问题标题】:QByteArray conversion and pointer castingQByteArray 转换和指针转换
【发布时间】:2016-05-14 09:34:26
【问题描述】:

我正在使用 Qt 和 C++。我必须管理电子板的错误代码。我可以以必须将其转换为 QVariant 的 QByteArray 的形式获取这些错误。我没有找到任何实用的方法来做到这一点(所以如果你有一个我在这里听)。无论如何,试图将它(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* 并且演员 quint64* 做了一个 reinterpret_cast (如果我很好地解释了这里所说的:When should static_cast, dynamic_cast, const_cast and reinterpret_cast be used?)。这个理由对吗?

  2. qVariantOut = QVariant(*(static_cast&lt;quint64*&gt;(value.data()) )); 这个不起作用,因为我正在尝试直接对 quint64* 进行 static_cast。但在这里我有一个问题:为什么不能从 char* 转换为 quint64*。难道它们不是一些必须可以使用 static_cast 的基本 (POD) 类型吗?

我想更好地理解这些转换...我什至发现有人说:“如果您需要转换指针,请通过 void* 转换它们”。评论?

  1. qVariantOut = QVariant( (quint64*)(value.data()) ); 这有点像奖金。我正在尝试使用此代码在 QVariant 中放入一个指针...这给了我错误“QVariant::QVariant(void) 在此上下文中是私有的* " 我不明白这是什么意思。

谢谢。

编辑:对于说这可能是 XY 问题的用户。这里有更多信息。我写了一个函数来从电子板上获取变量。这些变量可能是 QString、quint64、qint32、quint8 等等...在我的函数中,为了获取这些变量,我使用了一个 external 函数(来自外部库,由我公司的电子事业部,我必须使用但不能修改它)。为了使用这个外部函数,我需要作为参数传递:我要读取的变量(即:错误、警告、温度、固件版本...)、输出 QByteArray 和我要读取的变量的大小(例如错误->sizeof(quint64)、温度->sizeof(quint8))。正如你所理解的,这个外部函数返回一个 QByteArray。

我将代码转换为 quint64 的事实只是我的函数的一个例子。

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

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

【问题讨论】:

  • 我必须转换成 QVariant 为什么你需要这样做? (这篇文章闻起来像XY problem
  • 绝对是 XY 问题。我几乎可以保证,如果你清楚地说出你真正想要完成的事情,我可以在没有任何演员表的情况下完成。首先,什么是错误代码?一个字符串?一个 8 位的值?一个 32 位整数?您的代码使它看起来像错误代码是一个 64 位有符号整数,但这似乎是可疑的。
  • 我做了一个编辑,更详细地解释了我的情况:) peppe 和@ScottG

标签: c++ qt casting qbytearray


【解决方案1】:

有了您的更新,这并不像最初看起来那么疯狂。你有一个内部 API 将随机变量放入 QByteArray 而不是像 QVariant 这样的东西,这正是它的用途,这有点疯狂,但我知道你被你所拥有的东西困住了。

你有两个选择:

  1. 演员,但不需要做任何复杂的事情,只需使用reinterpret_cast。转换为void*,然后用static_cast 转换为其他内容与reinterpret_cast 相同,因此您不妨先调用reinterpret_cast

  2. memcpy(&amp;target, byteArray.data(), sizeof(target)); 这避免了强制转换,但几乎同样丑陋。从理论上讲,鉴于内存对齐问题,它会更安全一些(不必依赖 QByteArray 中的数据与 reinterpret_cast 正确对齐)。它还可以让您随心所欲地保留数据,而不会冒着在背后回收 QByteArray 中的内部指针的风险。

请注意,这两个选项仅适用于 POD 类型,但我假设除了 QString 之外,您返回的所有内容都是,对于 QString,您必须根据编码进行特殊情况(如果是,则非常简单ASCII/拉丁文1)。

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

【讨论】:

  • 我认为他们使用了 QByteArray(而不是 Qvariant),因为该特定功能甚至用于其他目的(在较低级别的上下文中)。无论如何,谢谢你的回答。我试过第2个。关于第一个,有人对我说,使用两个 static_cast 我会发现我尝试将指针转换为不同大小的情况......你同意吗? (其实我不明白这是什么意思)
  • 不做两个 static_casts,一个到 void* 然后一个到你的目标不会在这方面做任何事情。此外,如前所述, static_cast 甚至不适用于您尝试做的事情。一旦填充到 QByteArray 中,您将丢失有关原始对象大小的所有信息。
猜你喜欢
  • 1970-01-01
  • 2013-02-12
  • 1970-01-01
  • 2017-12-12
  • 1970-01-01
  • 2021-06-06
  • 2021-09-20
  • 1970-01-01
相关资源
最近更新 更多