초보자인데 질문하나만 드립니다. ^^;; stl map 호출이 안되서요.
글쓴이: balgarac1 / 작성시간: 금, 2014/10/31 - 12:57오후
우선 명령어와 명령어 처리 함수를 map에 저장해 놓았습니다. #ifndef _COMMNAD_HANDLER_H_ #define _COMMAND_HANDLER_H_ #include <iostream> #include <map> #include "ThreadClient.h" #include "user.h" using namespace std; class commandHandler { private: char cmd[20]; char sendBuff[BUFSIZ]; typedef void (commandHandler::*cmdHandler)(User &); // 멤버 함수 포인터를 사용했습니다. public: commandHandler(); ~commandHandler(); void cmdAppend(); void who(User&); void quit(User&); void user(User&); void talk(User&); void help(User&); void debug(User&); map<char *, cmdHandler> cmdHandlerMap; pair<map<char *, cmdHandler>::iterator, bool> mpair; }; #endif #----- commandHandler.cpp -----# //////////////////////////////// 아래와 같이 생성자를 호출하면서 map에 insert를 시켰습니다. #include "commandHandler.h" char *Usage[] = { "User <My ID>\n", "who\n", "talk <your ID> message start \n", "quit\n", "help\n", "debug\n", ". end of talk\n" }; commandHandler::commandHandler() { // constructor cmdAppend(); } commandHandler::~commandHandler() { // destructor cmdHandlerMap.clear(); // Map clear. } void commandHandler::cmdAppend() { mpair = cmdHandlerMap.insert(pair<char *, cmdHandler>("who", &commandHandler::who)); if (mpair.second == true) cout << "save complete." << endl; else cout << "save failed." << endl; cmdHandlerMap.insert(pair<char *, cmdHandler>("user", &commandHandler::user)); cmdHandlerMap.insert(pair<char *, cmdHandler>("talk", &commandHandler::talk)); cmdHandlerMap.insert(pair<char *, cmdHandler>("quit", &commandHandler::quit)); cmdHandlerMap.insert(pair<char *, cmdHandler>("help", &commandHandler::help)); cmdHandlerMap.insert(pair<char *, cmdHandler>("debug", &commandHandler::debug)); } void commandHandler::who(User &userInfo) { sprintf(sendBuff, "%s \r\n\r\n", "who"); send(userInfo.sock, sendBuff, strlen(sendBuff) + 2, 0); cout << "send ok" << endl; } void commandHandler::user(User &userInfo) { cout << "#-----USER-----#" << endl; cout << "Input Your ID:"; cin >> userInfo.ID; sprintf(sendBuff, "%s %s \r\n\r\n", "user", userInfo.ID); send(userInfo.sock, sendBuff, strlen(sendBuff) + 2, 0); cout << "send ok" << endl; } #-----THREADCLIENT_HEADER-----# /////////////////////////////// #ifndef __THREAD_CLIENT_H__ #define __THREAD_CLIENT_H__ #include <iostream> #include <process.h> #include <WinSock2.h> #include "user.h" #define BUFLEN 256 #pragma warning(disable:4996) using namespace std; class ThreadClient { private: SOCKET servSock; WSADATA wsaData; SOCKADDR_IN servAddr; HANDLE hThread[2]; commandHandler *cmdHandler; // 명령어 처리 함수를 호출할 수 있도록 commandHandler 포인터를 멤버 변수로 놓았습니다. User userData; public: ThreadClient(); ~ThreadClient(); void socketInit(); void socketStart(); void socketEnd(); void ErrorHandling(char *); }; unsigned WINAPI send_Msg(void * arg); unsigned WINAPI recv_Msg(void * arg); #endif #-----THREADCLIENT.CPP-----# //////////////////////////// #include "ThreadClient.h" #include "commandHandler.h" #include "user.h" HANDLE hMutex; typedef void(commandHandler::*cmdHandler)(User&); static map<char *, cmdHandler>::iterator iter; // 반복자가 필요한데 전역변수 이외에는 딱히 불러다가 쓸 수 있는 방법이 없어보여서 전역으로 선언했습니다. ThreadClient::ThreadClient() { //constructor cmdHandler = new commandHandler(); // commandHandler 객체를 동적할당합니다. } void ThreadClient::socketStart() { servSock = socket(PF_INET, SOCK_STREAM, 0); if (servSock == INVALID_SOCKET) { ErrorHandling("socket()"); } memset(&servAddr, 0, sizeof(servAddr)); servAddr.sin_family = AF_INET; servAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); servAddr.sin_port = htons(9190); if (connect(servSock, (SOCKADDR *)&servAddr, sizeof(servAddr)) == SOCKET_ERROR) { ErrorHandling("connect()"); } userData.sock = servSock; // 소켓 핸들 값을 저장하고, userData.cmdHand = cmdHandler; // 핸들러의 객체 주소를 저장해서 쓰레드의 데이터로 넘깁니다. hThread[0] = (HANDLE)_beginthreadex(NULL, 0, send_Msg, (void *)&userData, 0, NULL); // 쓰레드를 호출합니다. hThread[1] = (HANDLE)_beginthreadex(NULL, 0, recv_Msg, (void *)&userData, 0, NULL); WaitForMultipleObjects(2, hThread, FALSE, INFINITE); } unsigned WINAPI send_Msg(void * arg) { User *userInfo = (User *)arg; char Buff[BUFSIZ]; // char sendBuff[BUFSIZ]; char userComm[25]; WaitForSingleObject(hMutex, INFINITE); while (true) { memset(Buff, 0, sizeof(Buff)); memset(userComm, 0, sizeof(userComm)); //cout << "Input Msg:"; cin.getline(Buff, BUFLEN); // 유저에게 입력을 받아서 sscanf(Buff, "%s", userComm); // 명령어 부분만을 파싱한 뒤. iter = userInfo->cmdHand->cmdHandlerMap.find(userComm);//맵의 키값을 찾아서 value를 호출 but,호출실패,왜그런건가요? if (iter != userInfo->cmdHand->cmdHandlerMap.end()) iter->second; // void commandHandler::user(User &userInfo) user를 입력했으면 이 함수가 호출되야하는데요.. 호출이 안됩니다.. User 정보를 인자로 넘기지 않아서 그런것일수도 있나요?만약그렇다면 어떻게 넘겨야 하나요? } ReleaseMutex(hMutex); return 0; }
가르침 부탁드려용ㅇ^^;;
Forums:
...
자세히 읽어본 건 아니지만, iter->second 대신에 iter->second(인자) 형태로 써야 할 것 같은데요?
f가 함수 포인터일 때 그냥 f라고만 쓰면 아무 일도 일어나지 않습니다.
* 그리고 99%의 확률로 "statement has no effect" 같은 경고가 있어야 할 것 같은데 컴파일할 때 -Wall 주고 하셨는지...
음..
iter->second(인자) 이런 형태로 해보았는데 여전히 컴파일 오류가 나네요.
댓글 달기