2016-05-29 57 views
-1

我解决了我的问题,重新界定夫妻,但仍然有一个:重新定义在.h文件

错误2错误LNK2005: “类ConsoleCommandHandler commandHandler” 中已经定义IRC.obj C(commandHandler @@ 3VConsoleCommandHandler @@?A) :\用户\卢卡斯\桌面\ IRCClient主\ Magic.obj

这里是.h文件

magic.h

#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 

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 
} 

irc.h

#pragma once 
#include <iostream> 
#include <signal.h> 
#include <cstdlib> 
#include <map> 
#include <algorithm> 
#include "Magic.h" 
#include <msclr/marshal.h> 
#include <msclr/marshal_cppstd.h> 
#using <mscorlib.dll> 


namespace IRCclient { 

    using namespace System; 
    using namespace System::ComponentModel; 
    using namespace System::Collections; 
    using namespace System::Windows::Forms; 
    using namespace System::Data; 
    using namespace System::Drawing; 
    using namespace System::IO; 
    using namespace System::Runtime::InteropServices; 
    using namespace msclr::interop; 


    /// <summary> 
    /// Summary for MyForm 
    /// </summary> 


    private: System::Void connect_button_Click(System::Object^ sender, System::EventArgs^ e) 
    { 
     if ((server_box->Text == "") || (port_box->Text == "") || (username_box->Text == "") || (channel_box->Text == "")) 
     { 
      MessageBox::Show("Wypełnij wszystkie pola", "Puste pola", MessageBoxButtons::OK, MessageBoxIcon::Warning); 
      server_box->Focus(); 
     } 
     else 
     { 
      String^ host_string = server_box->Text; 
      char* host = (char*)(void*)Marshal::StringToHGlobalAnsi(host_string); 
      String^ port_string = port_box->Text; 
      int port; 
      //String^ port_string = port.ToString(); 
      String^ nick_string = username_box->Text; 
      std::string nick(marshal_as<std::string>(nick_string)); 
      std::string user = "test"; 


      IRCClient client; 
      volatile bool running; 
      Thread thread; 
      thread.Start(&inputThread, &client); 

      if (client.InitSocket()) 
      { 

       content_box->Text = "Socket initialized. Connecting..." + "\r\n"; 

       if (client.Connect(host, port)) 
       { 
        content_box->Text = "Connected. Loggin in..." + "\r\n";     

        if (client.Login(nick, user)) 
        { 
         content_box->Text = "Logged." + "\r\n";      

         running = true; 
         signal(SIGINT, signalHandler); 

         while (client.Connected() && running) 
          client.ReceiveData(); 
        } 

        if (client.Connected()) 
         client.Disconnect(); 

        content_box->Text = "Disconnected." + "\r\n"; 
       } 
      } 
     } 
    }; 
    }; 
}; 
+1

你的问题是什么? – Elyasin

+0

请编辑您的问题,并将代码缩减为MVCE,请参阅http://stackoverflow.com/help/mcve – kebs

+0

'ConsoleCommandHandler commandHandler;'在您的头文件中声明一个对象。并且,正如编译器已经正确指出的那样,当你将这个头文件包含到多个源文件中时,你就有了重新定义。 –

回答

1

Magic.h文件进行此更改:

extern ConsoleCommandHandler commandHandler; 

然后在Magic.cpp文件添加以下代码:

ConsoleCommandHandler commandHandler; 

否则,Magic.obj和IRC.obj将以ConsoleCommandHandler commandHandler结尾,因为标题将在每个obj文件中保留一次两次。

+0

没有帮助:( – titans

+0

@titans,我已经更新了我的答案,尝试将'ConsoleCommandHandler commandHandle'声明为'extern',并在cpp中添加'ConsoleCommandHandler commandHandle': – keith

+0

它有效,现在我遇到问题了在magic.cpp中使用magic.h中定义的volitale bool,但它显示了它在irc.h中的重定义,不知道为什么,因为它只被用在那里...... – titans