2016-05-29 51 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