有没有一种方法可以将结构索引为Glib哈希表中的值?

时间:2019-12-16 22:20:13

标签: c glib

目前我正在尝试通过作用域管理来实现一个符号tabel,以将自定义语言解释为学校项目。我的问题是我对实现容器的库知之甚少。我已经决定使用最合适的方法,但是我有一个问题是否可以使用结构作为键的值?

1 个答案:

答案 0 :(得分:0)

“将结构用作键的值”使我感到困惑,您是说“将结构用作键”还是“将结构用作值”?

您可以将任何指针用作键或值; gpointervoid*的typedef。将值构造为类似

YourStruct* your_struct_new(void) {
  YourStruct* val = g_malloc0(sizeof(YourStruct));
  /* Any per-struct initialization goes here */
  return val;
}

void your_struct_free(YourStruct* val) {
  /* Free any members you need to */
  g_free(val);
}

void do_stuff(void) {
  GHashTable* ht = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, your_struct_free);

  /* Insert an entry */
  g_hash_table_insert(ht, g_strdup("Key"), your_struct_new());

  /* Free the hash table, including all entries */
  g_hash_table_unref(ht);
}

作为键的结构可能需要自定义哈希/等于函数,除非您只想使用仅使用内存地址的g_direct_hash。通常这足够了,但是如果不是这样,您基本上就需要以某种方式从结构的内容生成一个int。例如,如果您的结构具有两个字符串成员,则可能需要

typedef struct {
  char* foo;
  char* bar;
} YourStruct;

guint your_struct_hash(YourStruct* val) {
  guint res = g_str_hash(val->foo);
  res |= g_str_hash(val->bar);
  return res;
}

/* return TRUE if a and b are equal, FALSE otherwise */
gboolean your_truct_equals(YourStruct* a, YourStruct* b) {
  if (g_strcmp0(a->foo, b->foo))
    return FALSE;
  if (g_strcmp0(a->bar, b->bar))
    return FALSE;

  return TRUE;
}

然后将它们传递给g_hash_table_new_full而不是g_str_hashg_free即可完成。当然,确切地实现这些方法很大程度上取决于您的数据结构,因此,在没有更多信息的情况下,我只能告诉您所有信息。