1

Winsock2 を使用してサーバーを作成しています。受信したデータはすべて文字列形式です。文字列形式で指定されたメソッド シグネチャからメソッド名と引数を取得できる文字列パーサーがあります。したがって、AddNewMember(arg1,arg2) は、AddNewMember を含む signature と呼ばれる文字列と、その要素に arg1 と arg2 を含む文字列のベクトルに分割されます。これはうまくいきます。これらのメッセージを意味のあるものにするために、メンバー関数ポインターへの文字列のマップがあり、すべての関数は同じパラメーター ベクトル引数を取ります。ServerControl クラスからのマップは次のとおりです。

//from header
map<string, string (ServerControl::*)(vector<string>)> functionMap;

//this on init creates all entries to function map
functionMap["AddNewMember"] = &ServerControl::AddNewMemberFunc;
functionMap["GetMember"] = &ServerControl::GetMemberFunc;
functionMap["RemoveMember"] = &ServerControl::RemoveMemberFunc;

...etc

次に、着信メッセージがその部分に解析されると、次のコードはマップにアクセスしてメンバー関数ポインターを取得します。

if (functionMap.find( signature ) != functionMap.end()) 
{
     return (this->*functionMap[message])(arguments); 
}

ここでも署名部分は「AddNewMethod」であり、引数は () の間に渡されるパラメータのベクトルです。

これは、引数ベクトルが空の場合は意図したとおりに機能しますが、ベクトルに引数が一度でも追加された場合、コードがこの行に到達してメンバー関数を呼び出そうとすると、メモリ アクセス違反が発生します。vector<string>*私はこれを、通常の と同様に引数で試しましたvector<string>。私は困惑しています。

私はこのプロジェクトで関数ポインターを使い始めたばかりなので、プロではありません。どんな助けでも大歓迎です!ありがとう

4

1 に答える 1

1

を使用signatureしてマップを検索していますが、を使用messageしてマップからメンバーポインタを取得しています。signatureとが同じ値でない場合messageは、期待するポインターを取得できmessageません。値がマップにまだ存在しない場合は、NULLポインターでさえも取得できます。signatureポインタを取得するときに再度使用する必要があります。[]さらに良いことに、すでに1回検索を実行しているので、オペレーターを呼び出して同じ検索を2回実行するのではなく、検索結果を使用する必要があります。

これを試して:

typedef string (ServerControl::*VectorArgMember)(vector<string>);
map<string, VectorArgMember> functionMap;

map<string, VectorArgMember>::iterator i = functionMap.find( signature );
if (i != functionMap.end()) 
{
    VectorArgMember memberPtr = i->second;
    return (this->*memberPtr)(arguments); 
}
于 2013-03-04T19:21:10.057 に答える