1
votes

Im writing a server using Winsock2. All the data received is in string form. I've got a string parser which can pull a method name and the arguments from a method signature given in string form. So AddNewMember(arg1,arg2) gets split into a string called signature containing AddNewMember and a vector of strings containing arg1 and arg2 in its elements. This works fine. In order to make these messages meaningful I have a map of strings to member function pointers, all the functions take the same parameter vector args. Here's my map from my ServerControl class:

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

then once the incoming message has been parsed into its parts the following code accesses the map to get the member function pointer.

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

once again the signature part is the "AddNewMethod" and the arguments is the vector of paratmers passed in between the ( ).

This works as intended if the arguments vector is empty, but if even once argument is added to the vector, when the code reaches this line and tries to call the member function I get a memory access violation. Ive tried this with arguments being a vector<string>* as well as an ordinary vector<string>. I'm baffled.

I've only really started using function pointers on this project so I'm not pro. Any help would be greatly appreciated! Thanks

1

1 Answers

1
votes

You are using signature to search the map, but then using message to retrieve a member pointer from the map. If signature and message are not the same value, you will not get the pointer you are expecting, maybe even a NULL pointer if the message value does not exist in the map yet. You need to use signature again when retrieving the pointer. Better, since you have already performed the search once, you should use the result of the search instead of invoking the [] operator to perform the same search again a second time.

Try this:

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