C中的关联数组

我正在实施一种将一组数据传输到可编程encryption狗的方法。 encryption狗基于智能卡技术,可以在其中执行任意代码。 input和输出数据作为可以通过input和输出指针访问的二进制块传递。

我想用一个关联数组来简化数据处理代码。 一切都应该这样工作:

首先是主机应用程序:

// Host application in C++ in_data["method"] = "calc_r"; in_data["id"] = 12; in_data["loc_a"] = 56.19; in_data["loc_l"] = 44.02; processor->send(in_data); 

接下来encryption狗内的代码:

 // Some dongle function in C char* method_name = assoc_get_string(in_data, "method"); int id = assoc_get_int(in_data, "id"); float loc_a = assoc_get_float(in_data, "loc_a"); float loc_l = assoc_get_float(in_data, "loc_l"); 

所以我的问题是关于encryption狗部分的function。 是否有C代码或库来实现像上面这样的关联数组行为?

我的怀疑是,你将不得不写你自己的。 如果我了解您所描述的架构,那么您将需要将整个数据块发送到一块。 如果是这样,那么大多数图书馆将不会为此工作,因为他们很可能会分配多个内存,这将需要多次传输(以及对内部结构的理解)。 这与尝试使用库散列函数,然后通过将networking中的根指针传递给send函数在套接字上通过networking发送它的内容相似。

可以编写一些你自己的工具来pipe理一个非常简单的关联数组(或散列)在一块内存中。 如果数据量很小,它可以使用一个简单的线性search条目,将是一个相当紧凑的代码。

Glib的哈希表。 实现一个地图接口或(关联数组)。 这很可能是C中最常用的散列表实现

 GHashTable *table=g_hash_table_new(g_str_hash, g_str_equal); /* put */ g_hash_table_insert(table,"SOME_KEY","SOME_VALUE"); /* get */ gchar *value = (gchar *) g_hash_table_lookup(table,"SOME_KEY"); 

试试uthash ,这是一个用C语言实现哈希表的头文件库。它很小且相当容易使用。

是的,但不会按照您指定的方式工作。 它将使用一个struct来存储在该结构上运行的数据和函数,从而为您提供所需的结果。 请参阅C中的简单关联数组库 。 使用示例:

 struct map_t *test; test=map_create(); map_set(test,"One","Won"); map_set(test,"Two","Too"); map_set(test,"Four","Fore"); 

GLib的哈希表和平衡二叉树可能就是你所追求的。

马克·威尔金斯给了你正确的答案。 如果要将数据作为单个块发送,则需要了解在架构中如何表示C ++映射并编写访问函数。

无论如何,如果你决定重新创buildencryption狗上的地图,我写了一个小型的C库,你可以这样写:

 tbl_t in_data=NULL; tblSetSS(in_data,"method","calc_r"); tblSetSN(in_data,"id",12); tblSetSF(in_data,"loc_a",56.19); tblSetSF(in_data,"loc_l",44.02); 

接着:

 char *method_name = tblGetP(in_data, "method"); int id = tblGetN(in_data, "id"); float loc_a = tblGetF(in_data, "loc_a"); float loc_l = tblGetF(in_data, "loc_l"); 

散列表是Hopscotch散列的一种变体,平均而言相当不错,您可以将任何types的键和数据混合使用(即可以使用整个表作为键)。

这个function的重点是简化编程而不是纯粹的速度,代码没有经过彻底的testing,但是如果你喜欢这个想法并且想要扩展它,你可以看看googlecode上的代码。

(还有其他的东西,比如可变长度的string和一个快速的sttring模式匹配函数,但是在这种情况下可能不感兴趣)。

Binn序列化格式是C语言中数据传输的一个很好的解决scheme。

binn对象(如JSON对象)是一个关联数组。 这是一个用法示例:

  binn *obj; // create a new object obj = binn_object(); // add values to it binn_object_set_str(obj, "method", "calc_r"); binn_object_set_int32(obj, "id", 12); binn_object_set_float(obj, "loc_a", 56.19); binn_object_set_float(obj, "loc_l", 44.02); // send over the network send(sock, binn_ptr(obj), binn_size(obj)); // release the buffer binn_free(obj); 

并阅读:

  char* method_name = binn_object_str(obj, "method"); int id = binn_object_int32(obj, "id"); float loc_a = binn_object_float(obj, "loc_a"); float loc_l = binn_object_float(obj, "loc_l"); 

它只是2个文件(binn.c和binn.h),所以它可以在项目中编译,而不是用作共享库。

但是我不知道它是否适合encryption狗。

这是一个古老的线程,但我认为这可能仍然是有用的任何人在那里寻找一个实现。 它不需要太多的代码; 我在没有任何额外的图书馆的约100行我的。 我把它叫做字典,因为它与python数据types相似。 这是我的代码:

 #include <stdlib.h> #include <stdio.h> #include <stdbool.h> typedef struct hollow_list hollow_list; struct hollow_list{ unsigned int size; void *value; bool *written; hollow_list *children; }; //Creates a hollow list and allocates all of the needed memory hollow_list hollow_list_create(unsigned int size){ hollow_list output; output = (hollow_list) {.size = size, .value = (void *) 0, .written = calloc(size, sizeof(bool)), .children = calloc(size, sizeof(hollow_list))}; return output; } //Frees all memory of associated with a hollow list and its children void hollow_list_free(hollow_list *l, bool free_values){ int i; for(i = 0; i < l->size; i++){ hollow_list_free(l->children + i, free_values); } if(free_values){ free(l->value); } free(l); } //Reads from the hollow list and returns a pointer to the item's data void *hollow_list_read(hollow_list *l, unsigned int index){ if(index == 0){ return l->value; } unsigned int bit_checker; bit_checker = 1<<(l->size - 1); int i; for(i = 0; i < l->size; i++){ if(bit_checker & index){ if(l->written[i] == true){ return hollow_list_read(l->children + i, bit_checker ^ index); } else { return (void *) 0; } } bit_checker >>= 1; } } //Writes to the hollow list, allocating memory only as it needs void hollow_list_write(hollow_list *l, unsigned int index, void *value){ if(index == 0){ l->value = value; } else { unsigned int bit_checker; bit_checker = 1<<(l->size - 1); int i; for(i = 0; i < l->size; i++){ if(bit_checker & index){ if(!l->written[i]){ l->children[i] = hollow_list_create(l->size - i - 1); l->written[i] = true; } hollow_list_write(l->children + i, bit_checker ^ index, value); break; } bit_checker >>= 1; } } } typedef struct dictionary dictionary; struct dictionary{ void *value; hollow_list *child; }; dictionary dictionary_create(){ dictionary output; output.child = malloc(sizeof(hollow_list)); *output.child = hollow_list_create(8); output.value = (void *) 0; return output; } void dictionary_write(dictionary *dict, char *index, unsigned int strlen, void *value){ void *hollow_list_value; dictionary *new_dict; int i; for(i = 0; i < strlen; i++){ hollow_list_value = hollow_list_read(dict->child, (int) index[i]); if(hollow_list_value == (void *) 0){ new_dict = malloc(sizeof(dictionary)); *new_dict = dictionary_create(); hollow_list_write(dict->child, (int) index[i], new_dict); dict = new_dict; } else { dict = (dictionary *) hollow_list_value; } } dict->value = value; } void *dictionary_read(dictionary *dict, char *index, unsigned int strlen){ void *hollow_list_value; dictionary *new_dict; int i; for(i = 0; i < strlen; i++){ hollow_list_value = hollow_list_read(dict->child, (int) index[i]); if(hollow_list_value == (void *) 0){ return hollow_list_value; } else { dict = (dictionary *) hollow_list_value; } } return dict->value; } int main(){ char index0[] = "hello, this is a test"; char index1[] = "hello, this is also a test"; char index2[] = "hello world"; char index3[] = "hi there!"; char index4[] = "this is something"; char index5[] = "hi there"; int item0 = 0; int item1 = 1; int item2 = 2; int item3 = 3; int item4 = 4; dictionary d; d = dictionary_create(); dictionary_write(&d, index0, 21, &item0); dictionary_write(&d, index1, 26, &item1); dictionary_write(&d, index2, 11, &item2); dictionary_write(&d, index3, 13, &item3); dictionary_write(&d, index4, 17, &item4); printf("%d\n", *((int *) dictionary_read(&d, index0, 21))); printf("%d\n", *((int *) dictionary_read(&d, index1, 26))); printf("%d\n", *((int *) dictionary_read(&d, index2, 11))); printf("%d\n", *((int *) dictionary_read(&d, index3, 13))); printf("%d\n", *((int *) dictionary_read(&d, index4, 17))); printf("%d\n", ((int) dictionary_read(&d, index5, 8))); } 

不幸的是,你不能复制列表[x]的语法,但这是我想出的最好的select。