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
(したがって、コマンドUserMap.h
によってUserMap.cpp
生成されますslice2cpp UserMap.ice
)。3つの仮想メソッドと別のプライベートヘルパー関数を実装Server.cpp
するクラスが呼び出されます UserMapI:public UserMap
と ですべての関数 (メソッド) を宣言したとコンパイラが判断するため、エラーが生成されUserMap.h
ますUserMap.cpp
。
この問題に対する私の理解では、UserMapI
宣言された inServer.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
コマンドは、このファイルをサーバーとクライアント間の API として機能する.h
とファイルにスライスします。.cpp
私には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
です。