0

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です。

4

0 に答える 0