2011-02-01 40 views
35

私はプログラム可能なドングルに一連のデータを転送する方法を実装しています。ドングルはスマートカード技術に基づいており、内部で任意のコードを実行することができます。入力および出力データは、入力および出力ポインタを介してアクセスできるバイナリブロックとして渡されます。Cの連想配列

連想配列を使用してデータ処理コードを簡素化したいと考えています。すべてがこのように動作する必要があります

まずホストアプリケーション:

// 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); 

次ドングル内のコード:

// 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"); 

だから私の質問は、ドングルの一部の機能についてですが。上記のような連想配列の動作を実装するCコードやライブラリはありますか?

答えて

7

私は、あなた自身で書く必要があるという疑いがあります。あなたが記述しているアーキテクチャを理解していれば、データ全体を単一の部分で送る必要があります。そうであれば、大部分のライブラリは複数のメモリを割り当てている可能性が高いため、複数の転送(および内部構造の理解)を必要とするため、動作しません。ライブラリのハッシュ関数を使用して、その内容をソケット上のネットワーク経由で送信することは、send関数へのルートポインタを渡すだけです。

非常に単純な連想配列(またはハッシュ)を1つのメモリブロックに管理する独自のユーティリティを書くことができます。データの量が少ない場合、エントリの単純な線形検索を使用することができ、かなりコンパクトなビットのコードになります。

+0

はい、あなたは正しいです。ドングルのデータ処理機能は、単一のデータを処理します。私は本当に私は8文字の長さのインデックスとリニアインデックスの検索アルゴリズムと言う単純な連想配列を実装する必要があるように感じる!私はちょうど車輪を再発明し、誰かがすでにそれを実装しているかどうか尋ねないと思った。 – ezpresso

+0

私は車輪を再発明しないことに間違いなく同意します。そして、確かに誰かが既にこれをやっているようです...しかし、それはむしろ専門的なので、それを見つけることは難しいかもしれません。 –

18

Glib's hash table.は、マップインターフェイスまたは(連想配列)を実装します。 そして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"); 
2

のGLibのHash TablesBalanced Binary Treesはあなたが後にしているものであるかもしれないことが、最も可能性の高い、最も使用されるハッシュテーブルの実装です。

3

はい、指定したとおりに動作しません。代わりにstructを使用して、その構造体で動作するデータと関数を格納し、必要な結果を得ます。 A Simple Associative Array Library In Cを参照してください。使用例:

struct map_t *test; 

test=map_create(); 
map_set(test,"One","Won"); 
map_set(test,"Two","Too"); 
map_set(test,"Four","Fore"); 
9

Cでハッシュテーブルを実装するヘッダーライブラリuthashを試してみてください。使用するのが簡単で、使いやすいです。

2

Mark Wilkinsが正しい答えをくれました。データを単一のチャンクとして送信する場合は、C++マップがアーキテクチャでどのように表現されているかを理解し、アクセス関数を記述する必要があります。あなたはドングル上のマップを再作成することにした場合とにかく、私はあなたが書くことができ、小さな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ハッシュのバリエーションであり、平均的にはかなり優れています。キーとデータのタイプを自由に組み合わせることができます(テーブル全体をキーとして使用できます)。

この機能の焦点は、純粋なスピードではなくイージングプログラミングであり、コードは完全にテストされていませんが、アイデアが好きでそれを拡張したい場合は、googlecodeのコードをご覧ください。

(可変長文字列と高速のsttringパターンマッチング機能のようなものがありますが、この場合は重要ではないかもしれません)。

1

Binnシリアライゼーション形式はC.

(JSONオブジェクトなど)BINNオブジェクトのデータ転送のための良い解決策である連想配列です。

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)であるので、それが使用されているのではなく、プロジェクト内でコンパイルすることができますここでは使用例です共有ライブラリとして使用します。

しかし、それはドングルに収まるかどうかわかりません。

2

これは古いスレッドですが、実装を探している人にとってはこれがまだ役立つと思いました。あまりにも多くのコードを取りません。私は余分なライブラリなしで〜100行で私の仕事をしました。私はPythonのデータ型と並行して(並べ替え)辞書と呼ばれました。ここに私のコードです:

#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]の構文を複製することはできませんが、これは私が出ている最良の選択肢です。