我正在使用 ZeroC 的 ICE 编写一个简单的服务器程序。当我尝试链接 .o 文件时,它给了我以下错误消息:
$ c++ -o server UserMap.o Server.o -L/Library/Developer/Ice-3.5.0/lib -lIce -lIceUtil
Undefined symbols for architecture x86_64:
"VTT for UserMapI", referenced from:
UserMapI::UserMapI() in Server.o
"vtable for UserMapI", referenced from:
UserMapI::UserMapI() in Server.o
NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
经过一番谷歌搜索后,我了解到问题是我有一个抽象类,其中声明了 3 个虚拟方法UserMap.ice
(因此在command 中声明UserMap.h
并由UserMap.cpp
command 生成slice2cpp UserMap.ice
),并且Server.cpp
我有一个名为的类UserMapI:public UserMap
,它实现了三个虚拟方法和另一个私有帮助函数。生成错误是因为编译器认为我已经在UserMap.h
and中声明了所有函数(方法) UserMap.cpp
。
我对这个问题的理解是我应该修改链接命令,以便链接器知道在UserMapI
声明中还有更多的函数Server.cpp
,但是我没有足够的知识来进行修改。有人能帮助我吗?
谢谢你们。
这是我用来获取Server.o
和的编译器命令UserMap.o
:
c++ -I. -I/Library/Developer/Ice-3.5.0/include -c UserMap.cpp Server.cpp
这是代码UserMap.ice
:
module DR
{
class UserMap
{
void addUserToLocation(int userID, int x, int y);
string getUsersNearLocation(int x, int y, int distance);
void removeFromMap(int userID, int x, int y);
};
};
slice2cpp
命令将这个.ice
文件分割成一个.h
和一个.cpp
文件,作为服务器和客户端之间的 API。
在Server.cpp
我有以下包括:
#include <Ice/Ice.h>
#include "UserMap.h"
#include <map>
#include <string>
#include <vector>
#include <iostream>
#include <sstream>
和以下子类:
class UserMapI : public UserMap
{
public:
virtual void addUserToLocation(int userID, int x, int y, const Ice::Current &);
virtual string getUsersNearLocation(int x, int y, int distance, const Ice::Current &);
virtual void removeFromMap(int userID, int x, int y, const Ice::Current &);
private:
string stringify(int x, int y);
};
在实现所有方法之后,main
函数如下:
int main(int argc, char* argv[])
{
int status = 0;
Ice::CommunicatorPtr ic;
try {
ic = Ice::initialize(argc, argv);
Ice::ObjectAdapterPtr adapter = ic->createObjectAdapterWithEndpoints("SimpleUserMapAdapter", "default -p 10000");
Ice::ObjectPtr object = new UserMapI;
adapter->add(object, ic->stringToIdentity("SimpleUserMap"));
adapter->activate();
ic->waitForShutdown();
} catch (const Ice::Exception & e) {
cerr << e << endl;
status = 1;
} catch (const char * msg) {
cerr << msg << endl;
status = 1;
}
if (ic){
try {
ic->destroy();
} catch (const Ice::Exception & e) {
cerr << e << endl;
status = 1;
}
}
return status;
}
这是UserMap.h
.