我一直在尝试为 Xcode 中的自定义字符串类型创建自定义数据格式化程序。下面的代码让我得到字符串中第一个字符的地址:
def MyStringSummary(valobj, internal_dict):
data_pointer = valobj.GetChildMemberWithName('AllocatorInstance').GetChildMemberWithName('Data')
print data_pointer.GetValue()
打印出指针地址。当我查看该地址的内容时,我可以看到用于存储该数据的宽字符,所以我想我要做的是将这个指针转换为wchar_t
然后我得到第一个字符。我的第一个方法是:
if data_pointer.TypeIsPointerType():
mychar = data_pointer.Dereference()
print mychar.GetValue()
else:
print "data_pointer is not a pointer!"
这证实了 data_pointer是一个指针,但Dereference()
调用似乎没有解决任何问题:mychar.GetValue()
只是返回None
。另一个问题 - 然后我是否能够通过一个循环并data_pointer
每次将地址增加一个固定数量并继续取消引用并找到下一个字符,然后将其添加到输出字符串中?如果是这样,我该怎么做?
编辑:
为了帮助澄清问题,我将发布一些关于字符串底层数据结构的信息。该定义太长,无法在此处发布(它也继承了它从通用数组基类所做的大部分工作),但我将提供更多详细信息。
查看StringVar.AllocationInstance.Data
指针位置时,我可以看到我们为每个字符使用了 16 位。我正在查看的字符串中的所有字符都只有 8 位,每个字符后面还有 8 位 0。所以,这就是我在调试器中执行此操作时发生的情况:
(lldb) p (char*)(StringVar.AllocatorInstance.Data)
(char *) $4 = 0x10653360 "P"
(lldb) p (char*)(StringVar.AllocatorInstance.Data)+1
(char *) $6 = 0x10653361 ""
(lldb) p (char*)(StringVar.AllocatorInstance.Data)+2
(char *) $7 = 0x10653362 "a"
所以我假设它一次只显示一个字符的原因是因为它认为每个 8 位字符都以以下 8 位为空终止。但是,当我投给我时,unsigned short
我得到了这个:
(lldb) p (unsigned short*)(StringVar.AllocatorInstance.Data)
(unsigned short *) $9 = 0x10653360
(lldb) p *(unsigned short*)(StringVar.AllocatorInstance.Data)
(wchar_t) $10 = 80
(lldb) p (char*)(unsigned short*)(StringVar.AllocatorInstance.Data)
(char *) $11 = 0x10653360 "P"
(lldb) p (char*)((unsigned short*)(StringVar.AllocatorInstance.Data)+1)
(char *) $14 = 0x10653362 "a"
(lldb) p (char*)((unsigned short*)(StringVar.AllocatorInstance.Data)+2)
(char *) $18 = 0x10653364 "r"
...所以看起来转换unsigned short
为很好,只要我们将每个整数转换为一个字符。知道如何尝试将其放入 Python 数据格式化程序中吗?