2016-06-13 46 views
0

經過幾年時間,我用概念證明回到了C++。我有一個hpp文件,它定義了一個類,一個帶有類方法的cpp文件和一個用於測試的main.cpp。我試圖創建一個運行在它自己的線程中的tcp服務器(只調用一次)。我開始使用同一個cpp文件中的所有代碼,並開始工作,但現在我已經將類和方法放在自己的文件中,因此出現編譯錯誤。C++ 11如何在其他類或源文件中引用類方法

我已經搜索,但沒有找到任何工作。我試過使用extern,'singleton'等方法,這些都會導致各種錯誤消息。我知道我沒有提供正確的方法參考。

tcpserver.hpp

#ifndef __TCP_SERVER_HPP_INCLUDED__ 
#define __TCP_SERVER_HPP_INCLUDED__ 

#include <string> 

class Server { 
    public: 

     static void *tcp_server(void * dummy); 
     static void hello(); 
     static int parseCmd(const char *cmd, char *reply); 
     static int copystring(char *reply, const char *msg); 

    private: 

}; 

#endif 

tcpserver.cpp,與類方法作爲存根:

#include <iostream> 
#include <cstdlib> 
#include <pthread.h> 
#include <unistd.h> 
#include <cstring>  // Needed for memset 
#include <sys/socket.h> // Needed for the socket functions 
#include <netdb.h>  // Needed for the socket functions 
#include <string.h> 

#include "tcpserver.hpp" 

int Server::parseCmd(const char *cmd, char *reply) { 
    //does stuff 
} 


int Server::copystring(char *dst, const char *src) { 
    // does stuff 
    return (int) ((std::string) dst).length(); 
} 


void Server::hello() { 
    std::cout << "Server says 'hello'." << std::endl; 
} 


void *Server::tcp_server(void * dummy) { 
    const char *port = "5555"; 
    // does a lot of stuff 
} 

main.cpp

#include <iostream> 
#include <pthread.h> 

#include "tcpserver.hpp" 

int main() { 
    Server server; 
    server.hello(); // 'Canary' method FIRST ERROR 

    // Initialize and set thread joinable 
    pthread_attr_t attr; 
    pthread_attr_init(&attr); 
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); 

    pthread_t serverthread; 
    int rc; 
    // **** tcp_server method must be static **** 
    rc = pthread_create(&serverthread, NULL, server.tcp_server, NULL); 
     if (rc){ 
      std::cout << "Error:unable to create thread," << rc << std::endl; 
      exit(-1); 
     } 
    std::cout << "Main() started thread." << std::endl; 
    pthread_attr_destroy(&attr); 
    void *status; 
     rc = pthread_join(serverthread, &status); 
     if (rc){ 
      std::cout << "Error:unable to join," << rc << std::endl; 
      exit(-1); 
     } 


    return 0 ; 
} 

makefile

all : main.o tcpserver.o 
    g++ -std=c++11 -o tcpserver main.o tcpserver.o 

tcpserver.o: tcpserver.cpp tcpserver.hpp 
    g++ -std=c++11 tcpserver.hpp 

main.o : main.cpp tcpserver.hpp 
    g++ -std=c++11 main.cpp -lpthread 

clean: 
    rm -f tcpserver.o main.o tcpserver 
+6

你收到了哪些錯誤信息?另外,'__TCP_SERVER_HPP_INCLUDED__'是一個保留名稱 - 不要使用雙下劃線。 – Barry

+0

通過類實例調用靜態函數有點奇怪(允許,但很奇怪)。你真的打算這些功能是靜態的嗎? – GManNickG

+1

不相關,但你可以從C++ 11開始使用'std :: thread'。 'pthread'現在只是看起來糟糕! :) – Arunmu

回答

6

你的目標文件的編譯不正確:

​​

這些規則不表明您正在構建的目標文件,他們都表示,他們正在獨立自主地建設和鏈接應用程序。這就是爲什麼你會收到鏈接錯誤 - 你實際上並沒有將編譯main.cpp的結果與tcpserver.o聯繫起來。

你需要提供-c告訴gcc你不想鏈接,你是只是編譯。您還需要提供-o來告訴它在哪裏輸出結果。最後,你要編譯tcpserver.hpp而不是tcpserver.cpp

tcpserver.o: tcpserver.cpp tcpserver.hpp 
    g++ -std=c++11 -c tcpserver.cpp -o tcpserver.o 

main.o : main.cpp tcpserver.hpp 
    g++ -std=c++11 -c main.cpp -o main.o 

或者更短:

%.o : %.cpp tcpserver.hpp 
    g++ -std=c++11 -c $< -o [email protected] 

而且,這個規則是壞:

all : main.o tcpserver.o 
    g++ -std=c++11 -o tcpserver main.o tcpserver.o 

目標的規則是all,但它實際上會創建一個名爲的文件210。因此,如果您繼續重新運行make,它將繼續重建tcpserver,因爲文件all將繼續不存在。更改目標以匹配實際目標。這是你的連接標誌去:

tcpserver : main.o tcpserver.o 
    g++ -std=c++11 -o tcpserver $^ -lpthread 

此外,包括你使用後衛(__TCP_SERVER_HPP_INCLUDED__)是C++標準庫保留名稱。任何包含雙下劃線的名稱或以下劃線開頭且後跟大寫字母的名稱都不應在代碼中使用。

+0

我承認用makefiles(主要是VS開發這些天)超級生鏽,但是.hpp文件需要在makefile中列出嗎?我不認爲他們只要你的include目錄做得正確,並且正確地包含在.cpp文件中,那麼IMO看起來就像是OP在那裏放置的那樣。並且他們可能還需要'-lpthread'或者不需要? –

+0

@KevinAnderson他們爲make添加了依賴關係。因此,如果tcpserver.hpp更新,main.o將需要重建。他們必須確保你正確地重建東西 - 儘管你不想手寫它們。 – Barry

1

如前所述,這是一個彙編問題,-lpthread在錯誤的地方。

我使用推薦一個簡單的Makefile,趁着默認規則,依賴關係等,並且還設置各種警示

CXXFLAGS = -std=c++11 -Wall -Wextra -pedantic 
LDFLAGS = -lpthread 

tcpserver: main.o tcpserver.o 
    $(LINK.cc) $^ -o [email protected] 

clean: 
    rm -f tcpserver.o main.o tcpserver 

# DO NOT DELETE 

main.o: tcpserver.hpp 
tcpserver.o: tcpserver.hpp 

注:過去的4線(從不要刪除)有關的依賴關係該命令被自動的加入到Makefile中

makedepend -Y *.cpp 

這些警告將有助於修正錯誤:

tcpserver.cpp: In static member function ‘static int Server::parseCmd(const char*, char*)’: 
    tcpserver.cpp:14:1: warning: no return statement in function returning non-void [-Wreturn-type] 
} 
^ 
tcpserver.cpp: At global scope: 
tcpserver.cpp:12:34: warning: unused parameter ‘cmd’ [-Wunused-parameter] 
    int Server::parseCmd(const char *cmd, char *reply) { 
            ^
tcpserver.cpp:12:45: warning: unused parameter ‘reply’ [-Wunused-parameter] 
    int Server::parseCmd(const char *cmd, char *reply) { 
              ^
tcpserver.cpp:17:47: warning: unused parameter ‘src’ [-Wunused-parameter] 
    int Server::copystring(char *dst, const char *src) { 
               ^
tcpserver.cpp: In static member function ‘static void* Server::tcp_server(void*)’: 
tcpserver.cpp:29:17: warning: unused variable ‘port’ [-Wunused-variable] 
    const char *port = "5555"; 
        ^
tcpserver.cpp:31:1: warning: no return statement in function returning non-void [-Wreturn-type] 
    } 
    ^
tcpserver.cpp: At global scope: 
tcpserver.cpp:28:33: warning: unused parameter ‘dummy’ [-Wunused-parameter] 
    void *Server::tcp_server(void * dummy) { 
+0

使'死亡分隔符'死亡。 –

+1

在Makefile中,插入了空格以符合線內代碼的Markdown語法。請用表格替換它們。 –

相關問題