초보자인데 질문하나만 드립니다. ^^;; 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(인자) 이런 형태로 해보았는데 여전히 컴파일 오류가 나네요.
댓글 달기