将QString转换为uintptr_t,qt / c

Convert QString to uintptr_t, Qt / C++

本文关键字:qt QString 转换 uintptr      更新时间:2023-10-16

当我将模拟状态存储在JSON文件中时,我想使用对象的地址作为唯一标识符。因此,我将指针转换为我的对象转换为uintptr_t

Cat myCatptr = new Cat;
uintptr_t address= (uintptr_t)myCatptr;

现在我将address转换为QString:

QString str = QString::number(address); 

我可以轻松地将QString添加到qjsonobject。但是如何从QString转换为UINTPTR_T?

在我的计算机上,我知道sizeof(unsigned long long)sizeof(uintptr_t )都是8 Byte。因此我可以使用

address= (uintptr_t)str.toULongLong();

这总是正确的,独立于平台吗?这需要 所有平台的sizeof(uintptr_t) <= sizeof(unsigned long long)

如下所述,sizeof(unsigned long long) is always >= 8byte

再次摘要:

  1. 是我的安萨兹(Ansatz(,将其转换为长时间的无符号,然后将其转换为uintptr_t总是工作的?

  2. 如果没有,您知道在任何平台上有效的替代方案吗?

标准保证吗?否。想象一个平台qulonglong为64位,但是uintptr_t是一些魔术256位扩展类型。

另一方面,a(目前不存在此类平台;b(QT很可能在该平台上将qulonglong定义为256位,即使unsigned long long为64位;c(您没有太多选择:鉴于QString,您可以轻松地将其变成qulonglong的最长整数。

100%便携式解决方案是使用scanfSCNxPTR(这是将文本转换为uintptr_t的格式。

    const auto text = str.toStdString();            // Convert to std::string
    sscanf( text.c_str(), "%" SCNxPTR, &address );  // Convert to uintptr_t
    // additional error handling required.

SCANF的文档一般。一般形式是:

sscanf( pointer_to_const_char_array, format, &value1, &value2, ... );

uintptr_tSCNxPTR的文档在这里(我实际上是通过此答案找到了它。SCNxPTR是#Define宏,它扩展到字符串字面的字符文字,这是feed of sscanf的正确格式(以及SCANF家族中的其他(在十六进制中解码uintptr_t

它应该可以正常工作,无论您针对哪种现代平台,都有足够的空间适合指针。实际上,您可能会有点过分,您可以将指针直接投入到qulonglong并返回。我已经在X86和ARM,32位和64位构建上进行了测试。

您也可以将指针恰好位于特定平台上的任何尺寸,然后将其移动到字节数组中,然后在Base64编码中从该数据创建一个字符串,然后在转换后进行相反的操作。无论该平台上的指针尺寸如何,您都应该备份。

还有另一种更好的方法。您可以实现QHash<int, Cat *>注册表,而不是直接使用指针,而是为每个CAT分配一个唯一的整数ID,并将其与内存中的地址相关联。这具有在应用程序运行中持续存在的优势,因此,即使每次重新创建加载应用程序数据时,您的地址都会更改该特定对象。由于您提到"存储状态",我认为您想以在应用程序运行中持续存在的方式存储它。并且有零保证您会的,并且在应用程序运行时,在同一地址分配对象几乎是不可能的,因此任何保存的指针值都将为> useeless 。因此,可选的解决方案是将实际指针关联到会持续存在的整数ID,查找也可能比将字符串转换为来回整数更快。

我也认为我找到了一个解决方案。如果您看到任何错误,也许您可以对此发表评论。

我的解决方案使用qvariant。我注册数据类型uintptr_t,以便通过QVariant知道它:

Q_DECLARE_METATYPE(uintptr_t);在qt核心中定义。

然后...

Strand * myCatptr = strand;
uintptr_t address= (uintptr_t)myCatptr;
QString str = QString::number(address);
//string can be passed to QJsonObject
//...
//string gets loaded from QJasonObject again to a later point.
//Variant can be converted to uintptr_t, because I registered it
QVariant var = QVariant::fromValue(str);
address = var.value<uintptr_t>();

通过qvariant将QString转换为UIntptr_t。