当我将模拟的状态存储在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字节。因此我可以使用
address= (uintptr_t)str.toULongLong();
这是否始终正确,独立于平台?这需要这样做
适用于所有平台的sizeof(uintptr_t) <= sizeof(unsigned long long)
。
如上所述here,sizeof(unsigned long long) is always >= 8byte
。
再次总结:
我的Ansatz,将其转换为unsigned long long然后再转换为uintptr_t始终有效吗?
如果没有,您是否知道可以在任何平台上运行的替代方案?
答案 0 :(得分:1)
标准是否有保障?没有。想象一个qulonglong
为64位的平台是完全可行的,但uintptr_t
是一种神奇的256位扩展类型。
另一方面,a)目前不存在这样的平台; b)即使qulonglong
是64位,Qt也可能在该平台上将unsigned long long
定义为256位; c)您没有太多选择:给定QString
,您可以轻松将其转换为qulonglong
的最长整数。
100%便携式解决方案是使用scanf
和SCNxPTR
(这是将文本转换为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.
扫描文件的一般文件here。一般形式是:
sscanf( pointer_to_const_char_array, format, &value1, &value2, ... );
uintptr_t
和SCNxPTR
的文档是here(我实际上是通过this answer找到的。SCNxPTR
是一个#define宏,它扩展为string literal,它是提供给sscanf(以及scanf系列中的其他人)以十六进制解码uintptr_t
的正确格式。
答案 1 :(得分:0)
它应该可以正常工作,无论您使用哪个当代平台,都有足够的空间来容纳指针。实际上,你可能会有点过分,你可以直接指向qulonglong
并返回。我已经在x86和arm,32位和64位版本上对此进行了测试。
您还可以将指针放在特定平台上的任何大小,并将其移动到字节数组中,然后使用base64编码从该数据创建一个字符串,并在转换回时执行相反的操作。无论该平台上的指针大小如何,都应该备份这个。
还有另一种更好的方法。您可以实现QHash<int, Cat *>
注册表,而不是直接使用指针,为每个cat分配一个唯一的整数id,并将其与内存中的地址相关联。这具有跨应用程序运行持久化的优点,因此即使每次在加载时重新创建应用程序数据时其地址都发生更改,您也可以始终寻址该特定对象。既然你提到&#34;存储状态&#34;我假设您希望以跨应用程序运行的方式存储它。您将无法保证,并且在下次应用程序运行时将对象分配到同一地址几乎是不可能的,因此任何保存的指针值都将无用。因此,可选的解决方案是将实际指针与将持久存在的整数id相关联,查找也可能比将字符串来回转换为整数更快。
答案 2 :(得分:0)
我也认为我找到了解决方案。如果你发现任何错误,也许你可以对它发表评论。
我的解决方案使用QVariant。我注册了数据类型uintptr_t
,以便QVariant
知道它:
Q_DECLARE_METATYPE(uintptr_t);
。
则...
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。