2017-03-01 10 views
3

私はカーネルモジュールを作成しています。このモジュールでは、あらかじめ定義された文字列に対して入力をチェックする必要があります。 C++では、コンパイル時にハッシュを計算するconstexpr関数を作成することができます。私はいくつかの擬似コードはthe Jenkins hash functionを使用してC.CのConst式 - 文字列をハッシュする方法は?

でそれをする方法を探しています:

u32 hash(const char *key) 
{ 
    u32 hash, i; 
    size_t len; 

    len = strlen(key); 
    for(hash = i = 0; i < len; ++i) 
    { 
     hash += key[i]; 
     hash += (hash << 10); 
     hash ^= (hash >> 6); 
    } 
    hash += (hash << 3); 
    hash ^= (hash >> 11); 
    hash += (hash << 15); 
    return hash; 
} 


const u32 myStringList [] = { 
    hash("hello"), 
    hash("this is a text"), 
    hash("good morning") 
}; 

int findString(const char * searchStr) { 
    u32 h; 
    int i; 

    h = hash(searchStr); 
    for (i = 0; i < sizeof(myStringList)/sizeof(const u32); i++) { 
     if (h == myStringList[i]) return i; 
    } 
    return -1; 
} 

どのように仕事を得るためにそれを修正しますか?

答えて

5

私はあなたができるとは思わない、Cはconstexprまたはコンパイル時の評価がありません。だからこそ、多くの人がプリプロセッサ(C++ではあまり使われていない)に向いていますが、それを使った文字列処理(文字列 "construction"とは対照的)はそれほど簡単ではありません。

場合によっては、別の前処理ステップを追加することで回避できます。おそらく、いくつかの高水準言語(私が好むPython)を使用して必要なCコードを作成します。

これはオプションではない場合は、起動時にハッシュテーブルを一度初期化するだけです。明示的なinit関数がない場合(私はLinuxカーネルモジュールがそうであると信じます)、もちろん静的フラグを使用することができます:

static const char *strings[] = { "hello", "this is a text", "good morning", NULL }; 
static uint32_t myStringList[(sizeof strings/sizeof *strings) - 1]; 

void something(const char *string) 
{ 
    static bool hash_initialized = false; 
    if(!hash_initialized) 
    { 
    for(size_t i = 0; strings[i] != NULL; ++i) 
     myStringList[i] = hash(strings[i]); 
    hash_initialized = true; 
    } 
    if(hash_lookup(string)) 
    { 
    ... 
    } 
} 
関連する問題