Nat*_*ood 0 c++ static-methods makefile class c++11
经过几年的概念验证后,我又回到了C++.我有一个定义类的hpp文件,一个带有类方法的cpp文件和一个用于测试的main.cpp.我正在尝试创建一个在自己的线程中运行的tcp服务器(仅调用一次).我开始使用相同cpp文件中的所有代码并使其工作但是我现在得到了编译错误,因为我将类和方法放在他们自己的文件中.
我搜索过但没找到任何可行的东西.我尝试过使用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
Run Code Online (Sandbox Code Playgroud)
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
}
Run Code Online (Sandbox Code Playgroud)
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 ;
}
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
您的目标文件编译不正确:
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
Run Code Online (Sandbox Code Playgroud)
这些规则并不表示您正在构建目标文件,它们都表示它们是独立构建和链接应用程序.这就是你收到链接器错误的原因 - 你实际上并没有将编译结果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
Run Code Online (Sandbox Code Playgroud)
或者,更短:
%.o : %.cpp tcpserver.hpp
g++ -std=c++11 -c $< -o $@
Run Code Online (Sandbox Code Playgroud)
此外,这条规则很糟糕:
all : main.o tcpserver.o
g++ -std=c++11 -o tcpserver main.o tcpserver.o
Run Code Online (Sandbox Code Playgroud)
该规则的目标是all,但它实际上是一个名为的文件tcpserver.因此,如果您继续重新运行make,它将继续重建,tcpserver因为该文件all将继续不存在.更改目标以匹配实际目标.这是你的链接器标志去的地方:
tcpserver : main.o tcpserver.o
g++ -std=c++11 -o tcpserver $^ -lpthread
Run Code Online (Sandbox Code Playgroud)
此外,您正在使用的包含保护(__TCP_SERVER_HPP_INCLUDED__)是C++标准库的保留名称.任何包含双下划线或以下划线后跟大写字母开头的名称都不应在您的代码中使用.