C++ h文件中的重新定义
我解决了两个重新定义的问题,但仍然有一个: 错误2错误LNK2005:“类控制台命令处理程序commandHandler commandHandler”(?commandHandler@@3VConsoleCommandHandler@@A)已在IRC.obj C:\Users\Łukasz\Desktop\IRCClient master\Magic.obj中定义 这是.h文件 魔法C++ h文件中的重新定义,c++,class,redefinition,C++,Class,Redefinition,我解决了两个重新定义的问题,但仍然有一个: 错误2错误LNK2005:“类控制台命令处理程序commandHandler commandHandler”(?commandHandler@@3VConsoleCommandHandler@@A)已在IRC.obj C:\Users\Łukasz\Desktop\IRCClient master\Magic.obj中定义 这是.h文件 魔法 #ifndef Magic_h #define Magic_h #include <iostream&g
#ifndef Magic_h
#define Magic_h
#include <iostream>
#include <signal.h>
#include <cstdlib>
#include <map>
#include <algorithm>
#include "src\Thread.h"
#include "src\IRCClient.h"
void signalHandler(int signal);
class ConsoleCommandHandler
{
public:
bool AddCommand(std::string name, int argCount, void(*handler)(std::string /*params*/, IRCClient* /*client*/));
void ParseCommand(std::string command, IRCClient* client);
private:
struct CommandEntry
{
int argCount;
void(*handler)(std::string /*arguments*/, IRCClient* /*client*/);
};
std::map<std::string, CommandEntry> _commands;
};
ConsoleCommandHandler commandHandler;
void msgCommand(std::string arguments, IRCClient* client);
void joinCommand(std::string channel, IRCClient* client);
void partCommand(std::string channel, IRCClient* client);
void ctcpCommand(std::string arguments, IRCClient* client);
ThreadReturn inputThread(void* client);
#endif
\ifndef Magic\u h
#定义魔术
#包括
#包括
#包括
#包括
#包括
#包括“src\Thread.h”
#包括“src\IRCClient.h”
无效信号处理器(int信号);
类ConsoleCommandHandler
{
公众:
bool AddCommand(std::string name,int argCount,void(*handler)(std::string/*params*/,IRCClient*/*client*/);
void ParseCommand(std::string命令,IRCClient*client);
私人:
结构命令项
{
int argCount;
void(*handler)(std::string/*arguments*/,irclient*/*client*/);
};
std::map\u命令;
};
控制台命令处理程序命令处理程序;
void msgCommand(std::string参数,IRCClient*client);
void joinCommand(标准::字符串通道,IRCClient*客户端);
void partCommand(标准::字符串通道,IRCClient*客户端);
void ctcpCommand(std::字符串参数,IRCClient*client);
ThreadReturn输入线程(void*客户端);
#恩迪夫
magic.cpp
#include "Magic.h"
void signalHandler(int signal)
{
volatile bool running;
running = false;
};
bool ConsoleCommandHandler::AddCommand(std::string name, int argCount, void(*handler)(std::string /*params*/, IRCClient* /*client*/))
{
CommandEntry entry;
entry.argCount = argCount;
entry.handler = handler;
std::transform(name.begin(), name.end(), name.begin(), towlower);
_commands.insert(std::pair<std::string, CommandEntry>(name, entry));
return true;
}
void ConsoleCommandHandler::ParseCommand(std::string command, IRCClient* client)
{
if (_commands.empty())
{
std::cout << "No commands available." << std::endl;
return;
}
if (command[0] == '/')
command = command.substr(1); // Remove the slash
std::string name = command.substr(0, command.find(" "));
std::string args = command.substr(command.find(" ") + 1);
int argCount = std::count(args.begin(), args.end(), ' ');
std::transform(name.begin(), name.end(), name.begin(), towlower);
std::map<std::string, CommandEntry>::const_iterator itr = _commands.find(name);
if (itr == _commands.end())
{
std::cout << "Command not found." << std::endl;
return;
}
if (++argCount < itr->second.argCount)
{
std::cout << "Insuficient arguments." << std::endl;
return;
}
(*(itr->second.handler))(args, client);
}
struct CommandEntry
{
int argCount;
void(*handler)(std::string /*arguments*/, IRCClient* /*client*/);
};
std::map<std::string, CommandEntry> _commands;
void msgCommand(std::string arguments, IRCClient* client)
{
std::string to = arguments.substr(0, arguments.find(" "));
std::string text = arguments.substr(arguments.find(" ") + 1);
std::cout << "To " + to + ": " + text << std::endl;
client->SendIRC("PRIVMSG " + to + " :" + text);
};
void joinCommand(std::string channel, IRCClient* client)
{
if (channel[0] != '#')
channel = "#" + channel;
client->SendIRC("JOIN " + channel);
}
void partCommand(std::string channel, IRCClient* client)
{
if (channel[0] != '#')
channel = "#" + channel;
client->SendIRC("PART " + channel);
}
void ctcpCommand(std::string arguments, IRCClient* client)
{
std::string to = arguments.substr(0, arguments.find(" "));
std::string text = arguments.substr(arguments.find(" ") + 1);
std::transform(text.begin(), text.end(), text.begin(), towupper);
client->SendIRC("PRIVMSG " + to + " :\001" + text + "\001");
}
ThreadReturn inputThread(void* client)
{
std::string command;
commandHandler.AddCommand("msg", 2, &msgCommand);
commandHandler.AddCommand("join", 1, &joinCommand);
commandHandler.AddCommand("part", 1, &partCommand);
commandHandler.AddCommand("ctcp", 2, &ctcpCommand);
while (true)
{
getline(std::cin, command);
if (command == "")
continue;
if (command[0] == '/')
commandHandler.ParseCommand(command, (IRCClient*)client);
else
((IRCClient*)client)->SendIRC(command);
if (command == "quit")
break;
}
#ifdef _WIN32
_endthread();
#else
pthread_exit(NULL);
#endif
}
#包括“Magic.h”
无效信号处理器(int信号)
{
不稳定bool跑;
运行=错误;
};
bool ConsoleCommandHandler::AddCommand(std::string name,int argCount,void(*handler)(std::string/*params*/,IRCClient*/*client*/)
{
命令输入;
entry.argCount=argCount;
entry.handler=handler;
std::transform(name.begin()、name.end()、name.begin()、towlow);
_insert(std::pair(name,entry));
返回true;
}
void ConsoleCommandHandler::ParseCommand(std::string命令,IRCClient*客户端)
{
if(_commands.empty())
{
std::cout Text==“”)| |(端口盒->文本==“”)| |(用户名盒->文本==“”)| |(频道盒->文本==“”)
{
MessageBox::Show(“Wypełnij wszystkie pola”,“Puste pola”,MessageBoxButtons::OK,MessageBoxIcon::Warning);
服务器盒->焦点();
}
其他的
{
字符串^host\u字符串=服务器\u框->文本;
char*host=(char*)(void*)封送:StringToHGlobalAnsi(主机字符串);
字符串^port\u字符串=端口框->文本;
国际港口;
//字符串^port_String=port.ToString();
字符串^nick\u String=用户名\u框->文本;
std::字符串nick(marshal_as(nick_string));
std::string user=“test”;
irc客户端;
不稳定bool跑;
螺纹;
启动(输入线程和客户端);
if(client.InitSocket())
{
content\u box->Text=“套接字已初始化。正在连接…”+“\r\n”;
if(客户端连接(主机、端口))
{
content\u box->Text=“已连接。登录…”+“\r\n”;
if(客户端登录名(尼克,用户))
{
content\u box->Text=“Logged.”+“\r\n”;
运行=真;
信号(SIGINT,信号处理器);
while(client.Connected()&&running)
client.ReceiveData();
}
if(client.Connected())
client.Disconnect();
content\u box->Text=“已断开连接。”+“\r\n”;
}
}
}
};
};
};
在Magic.h文件中进行以下更改:
extern ConsoleCommandHandler commandHandler;
然后在Magic.cpp文件中添加以下代码:
ConsoleCommandHandler commandHandler;
否则,Magic.obj和IRC.obj都将以
ConsoleCommandHandler commandHandler
结束,因为标头将保留它两次,在每个obj文件中保留一次。您的问题是什么?请编辑您的问题并将代码简化为MVCE,请参阅ConsoleCommandHandler commandHandler头文件中的代码>正在声明一个对象。而且,正如编译器正确指出的那样,当您将此头文件包含到多个源文件中时,您需要重新定义。因此,我必须用它来修复它吗?在头文件中将其声明为extern
,并在一个源文件中定义它是一种方法。这样做没有帮助:(@titans,我已经更新了我的答案,尝试将ConsoleCommandHandler commandHandle
声明为extern
,并将ConsoleCommandHandler commandHandle
添加到cpp:-)它是有效的,现在我对magic中定义的volitale bool有一个问题。h在magic.cpp中使用,但它在irc.h中显示了它的重新定义,不知道为什么,因为它只在那里使用…@titans,在你为magic提供的源代码中。h我看不到volatile只在magic.cpp文件中使用。顺便说一句,如果你想要线程安全的话,使用std::atomic。
ConsoleCommandHandler commandHandler;