神秘的链接器错误
mysterious linker error
我写了一个简单的程序,使用了一些类和procol缓冲区。这些类使计算机之间的连接和发送消息变得更容易。编译成功。然而,链接器说:
server.o:在函数"main"中:
server.cpp:(.text+0x24):未定义参考`dataExchange::Server::Server(未签名int)'
服务器.cpp:(.text+0x39):对的未定义引用`dataExchange::Server::accept()'
server.cpp:(.text+0x51):未定义参考`dataExchange::连接::received()'collect2:ld返回1退出状态
代码:server.cpp:
#include <iostream>
#include "connection.h"
#include "protocol.pb.h"
using namespace std;
using namespace msg;
using namespace dataExchange;
int main() {
Server server(1234);
while(1) {
Connection con = server.accept();
Annoucement ann = con.receive();
cout << ann.typ() << endl;
}
}
connection.h:
namespace dataExchange {
class SocketMaintenance {
protected:
sockaddr_in addr;
int s;
public:
SocketMaintenance(const unsigned int) throw();
SocketMaintenance(const sockaddr_in, const int) throw();
SocketMaintenance(const SocketMaintenance&) throw();
~SocketMaintenance();
void write(const char*, const int);
};
class Connection {
FileOutputStream* raw_output;
FileInputStream* raw_input;
char buffer[1024];
public:
Connection(const char*, const unsigned int);// throw(WrongAddress);
Connection(const SocketMaintenance&);//throw(ConnectFailed);
void send(const Message&) throw();
Annoucement receive() throw();
};
class Server {
public:
Server(const unsigned int);// throw(BindFailed,ListenFailed);
Connection accept() throw();
};
}
链接器失败的原因是什么?
建造程序:
g++服务器.cpp-c;g++协议.pb.cc-c;g++连接.cpp-c;g++服务器.o协议.pb.o连接.o-lprotobuf
连接.cpp
using namespace std;
using namespace msg;
using namespace google::protobuf;
using namespace google::protobuf::io;
namespace dataExchange {
class SocketMaintenance {
protected:
sockaddr_in addr;
int s;
public:
SocketMaintenance(const unsigned int port) {
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
s = socket(AF_INET, SOCK_STREAM, 0);
}
SocketMaintenance(const sockaddr_in Addr, const int Socket) {
addr = Addr;
s = Socket;
}
SocketMaintenance(const SocketMaintenance& source) {
addr = source.addr;
s = source.s;
}
~SocketMaintenance() {
close(s);
}
void write(const char* buffer, const int n) {
::write(s, buffer, n);
}
};
class Connection : public SocketMaintenance {
FileOutputStream* raw_output;
FileInputStream* raw_input;
char buffer[1024];
public:
Connection(const char* IP, const unsigned int port) : SocketMaintenance(port) {
if(inet_pton(AF_INET, IP, &addr.sin_addr)<=0) {
throw WrongAddress();
}
if(connect(s, (sockaddr*)&addr, sizeof(addr))<0) {
throw ConnectFailed();
}
raw_output = new FileOutputStream(s);
raw_input = new FileInputStream(s);
}
Connection(const SocketMaintenance& source) : SocketMaintenance(source) {}
~Connection() {
delete raw_output;
}
void send(const Message& msg) throw(EmptyMessage) {
CodedOutputStream* coded_output = new CodedOutputStream(raw_output);
int n = msg.ByteSize();
if(n<=0) throw EmptyMessage();
coded_output->WriteVarint32(n);
delete coded_output;
raw_output->Flush();
msg.SerializeToArray(buffer, n);
SocketMaintenance::write(buffer, n);
}
Annoucement receive() throw() {
CodedInputStream* coded_input = new CodedInputStream(raw_input);
google::protobuf::uint32 n;
coded_input->ReadVarint32(&n);
char *b;
int m;
coded_input->GetDirectBufferPointer((const void**)&b, &m);
Annoucement ann;
ann.ParseFromArray(b, n);
return ann;
}
};
class Server : public SocketMaintenance {
public:
Server(const unsigned int port) : SocketMaintenance(port) {
addr.sin_addr.s_addr = htonl(INADDR_ANY);
if(bind(s, (struct sockaddr *)&addr, sizeof(addr))<0) {
throw BindFailed();
}
if(listen(s, 5)<0) {
throw ListenFailed();
}
}
Connection accept() throw() {
sockaddr_in client;
socklen_t client_len;
int client_socket = ::accept(s, (sockaddr*)&client, &client_len);
return Connection(SocketMaintenance(client, client_socket));
}
};
}
很可能忘记编译和/或链接
"connection.cpp"
。我至少希望你有这样一个文件,它实现了所有的功能
我认为您对.h和.cpp中的拆分方式存在一些根本性的误解。在.cpp中,您不需要简单地重新声明类,这一次是使用它们内部定义的函数。你需要这样做:
// connection.cpp
namespace dataExchange{
// define the constructor of Server
Server::Server(const unsigned int port)
: SocketMaintenance(port)
{
// ....
}
// define the accept function of Server
Connection accept() throw(){
// ...
}
// ...
}
但这只是问题的一部分,你似乎需要一本好的C++书。例如,您需要在声明类的头中进行任何继承。
当您#include "connection.h"
时,您会得到Server
方法的声明。这基本上告诉编译器存在什么方法,并使编译成功。
为了链接您的可执行文件,您需要链接这些方法的定义(即实现它们的实际代码)。对于connection.h
中定义的类,这些类通常位于名为connection.cpp
或类似文件中。您需要编译该文件,并在链接步骤中指定生成的对象文件。
您的项目上应该有一个实现构造函数Server::Server(const unsigned int)
的connection.cpp。你有吗?
您也可以帮助自己并粘贴您发出的命令进行编译,您可能缺少一个用于链接的文件。
- Netbeans 10:错误:链接器命令失败,退出代码为 1(使用 -v 查看调用)
- CMake 错误:链接器命令失败,退出代码为 1 和 cpp.o 文件
- clang:错误:链接器命令失败,退出代码为 1(使用 -v 查看调用) - 体系结构的未定义符号 x86_64:
- 如何修复 clang: 错误:链接器命令失败,退出代码为 1(使用 -v 查看调用)
- Android NDK.Build命令失败.未定义的引用.clang++:错误:链接器命令失败,退出代码为1
- 使用cmake错误链接boost日志
- 错误:链接器命令失败,退出代码为 1(使用 -v 查看调用):在 Macbook 上
- C++ XCODE ld:找不到体系结构x86_64 clang 的符号:错误:链接器命令失败,退出代码为 1(使用 -
- clang:错误:链接器命令失败,C++代码中的退出代码为 1(使用 -v 查看调用)
- 静态库中的 g++ 错误链接函数
- 未定义的参考错误链接天然函数Android
- C++编译错误:ld:找不到体系结构x86_64 clang 的符号:错误:链接器命令失败,退出代码为 1(使用 -v
- QT Q_PROPERTY错误:链接器命令失败,退出代码为 1(使用 -v 查看调用)
- ld:找不到体系结构x86_64 clang 的符号:错误:链接器命令失败,退出代码为 1(使用 -v 查看调用)
- OSX MOJAVE -LD:架构X86_64 clang找不到符号:错误:链接器命令失败,出口代码1
- C 错误链接器命令失败了出口代码1(使用-V查看调用)
- LD:架构x86_64 clang找不到符号:错误:链接器命令失败,出口代码1(使用-v to See
- 聚输出错误 - 链接列表
- Xcode链接器错误:链接器命令失败,退出代码为1(使用-v查看调用)
- 尝试构建C DLIB示例无法与数百个未定义的参考错误链接