2016-06-13 8 views
0

概念の証明とともに数年後にC++に戻ってきました。私はクラスを定義するhppファイル、クラスメソッドを持つcppファイル、テストのためのmain.cppを持っています。私は自分のスレッドで実行されるtcpサーバを作成しようとしています(一度だけ呼び出されます)。私は同じcppファイル内のすべてのコードで作業を開始しましたが、クラスとメソッドを独自のファイルに入れたのでコンパイルエラーが発生します。C++ 11他のクラスまたはソースファイルのクラスメソッドを参照する方法

私は検索しましたが、動作するものは見つかりませんでした。私はextern、 'シングルトン'メソッドなどを使用してみましたが、そのすべてがさまざまなエラーメッセージを引き起こします。私は、メソッドに対する正しい参照を提供していないことを知っています。

tcpserver.hpp

#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

スタブとしてクラスメソッドと

#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

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を再実行し続けると、ファイルallは引き続き存在しないため、tcpserverを再構築し続けます。実際のターゲットと一致するようにターゲットを変更します。そして、これはあなたのリンカのフラグが行くところされています。また、あなたが使用しているが含まガード(__TCP_SERVER_HPP_INCLUDED__)は、C++標準ライブラリの予約名です

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

。二重アンダースコアを含むか、アンダースコアで始まり大文字で始まる名前は、コード内で使用しないでください。

+0

私はmakefile(主にVS dev)でSUPER-rustyであることを認めますが、makefileにリストされるのに必要な.hppファイルはありますか?私は、あなたのインクルードディレクトリが正しく行われているとは思っていませんでしたし、.cppファイルに正しく含まれていました。また、 '-lpthread'または' -lpthread'を必要とするかもしれませんか? –

+0

@KevinAnderson makeの依存関係を追加します。したがって、tcpserver.hppが更新された場合、main.oを再構築する必要があります。あなたが手作業で書く必要はありませんが、正しく再構築するために必要です。 – Barry

1

前述のように、これはコンパイルの問題で、-lpthreadが間違った場所にあります。

私は、デフォルトのルール、依存関係などを活用しても警告のすべての種類

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 

注設定、Makefile単純なを使用してrecommand:依存関係について(削除しないで始まる)最後の4行を

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) { 
0123:自動的にコマンドでのMakefileに追加された

makedepend -Y *.cpp 

これらの警告はエラーを修正するために参考になります

+0

'セパレータがない'ダイを作成します。 –

+1

Makefileでは、インラインコードのMarkdown構文に準拠するためにスペースが挿入されました。それらを表に置き換えてください。 –

関連する問題