如何使用 SBSyntheticValueProvider 编写合成值数据格式化程序

How to write a synthetic value data formatter using SBSyntheticValueProvider

我有一个简单的模板化 C++ class storage_for<T>,它本质上将 T 类型的值存储在原始字符数组中。我想实现一个 lldb 数据格式化程序,它将字符数组转换为类型 T 并且只显示 T 的成员。所以假设我有一个变量 storage_for<std::pair<int, int>> s; 然后 Xcode 变量列表应该显示节点

s (storage_for<std::pair<int, int>>)
   first = ...
   secon = ...

没有显示类型 storage_for 的内部结构,也没有引入假的子元素。 From reading the documentation 我认为以下应该有效:

class storage_for_synth(lldb.SBSyntheticValueProvider): 
    def __init__(self, valobj, internal_dict):
        self.valobj = valobj

    def get_value(self):
        return self.valobj.GetChildMemberWithName('m_buffer').GetChildMemberWithName('__lx').Cast(self.valobj.GetType().GetTemplateArgumentType(0))

但事实并非如此。 get_value 中的表达式本身是正确的。但是 Xcode 变量列表和 lldb 控制台都没有显示任何我类型的变量。

这听起来像是正确的行为

get_value 的意思是 return 您的类型变量的值,例如如果你有

class Int {
  private: int m_value;
};

您可以使用 get_value 使您的 Int class 具有与其基础整数表示相同的值

在您的情况下,听起来您正在尝试使 SBValue 具有与聚合类型(您的基础 T)相同的值。聚合类型(即 classes)的值与 int 具有值的方式不同(这是设计使然 - 这些类型具有子值)

因此,LLDB 会将您的指令解释为使类型的值成为没有值的变量

您需要做的是在您的提供者中出售子值,并将它们作为您的基础 T

的子值出售

关于这一点,让我快速警告您,使用 SBValue::Cast() 进行非指针到指针的转换有时会做不到正确的事情(这是一个已知问题)- 我鼓励您将 m_buffer 从 char* 转换为 T*(如果有的话)