- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
经过几年的概念验证,我又回到了 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
tcpserver.cpp
,类方法作为 stub :
#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 ;
}
生成文件
:
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
最佳答案
你的目标文件编译不正确:
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
这些规则并不表示您正在构建目标文件,它们都表示它们正在独立构建和链接应用程序。这就是您遇到链接器错误的原因 - 您实际上并未将编译 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 $@
此外,这条规则是错误的:
all : main.o tcpserver.o
g++ -std=c++11 -o tcpserver main.o tcpserver.o
规则的目标是all
,但它实际上是在创建一个名为tcpserver
的文件。因此,如果您继续重新运行 make
,它将继续重建 tcpserver
,因为文件 all
将继续不存在。更改目标以匹配实际目标。这就是您的链接器标志所在的位置:
tcpserver : main.o tcpserver.o
g++ -std=c++11 -o tcpserver $^ -lpthread
此外,您使用的包含防护 (__TCP_SERVER_HPP_INCLUDED__
) 是 C++ 标准库的保留名称。任何包含双下划线或以下划线后跟大写字母开头的名称都不应在您的代码中使用。
关于C++11 如何在其他类或源文件中引用类方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37796960/
我是一名优秀的程序员,十分优秀!