1

以前の例を拡張しました: CORBA C++/Java アプリケーションのサーバー側でのセグメンテーション エラー (コア ダンプ)を、Stack のユーザー @Brian Neal の助けを借りて最終的に完成させました。

私はまだ Corba の初心者なので、Corba のシーケンスについてもう少し知りたいと思い、この単純な (?) 例を書きました。

interface Task
{
    string getThingToDo();
};

#include "Task.idl"

interface Employee
{
    typedef sequence <Task> tasks;
    string getLastname();
    Task getTask(in short id);
};

#include "Employee.idl"

interface Work
{
    Employee getEmployee(in short id);
};

TaskImpl.h および TaskImpl.cpp:

#include "Task.hh"

class TaskImpl : public POA_Task
{
    private:
        CORBA::String_var thingToDo;

    public:
        TaskImpl(const char* thingToDo);
        char* getThingToDo();
};

#include "TaskImpl.h"

TaskImpl::TaskImpl(const char* thingToDo)
{
    this->thingToDo = CORBA::string_dup(thingToDo);
}

char* TaskImpl::getThingToDo()
{
    return CORBA::string_dup(this->thingToDo.in());
}

EmployeeImpl.h および EmployeeImpl.cpp:

#include "Employee.hh"
#include "TaskImpl.h"

class EmployeeImpl : public POA_Employee
{
    private:
        CORBA::String_var lastname;
        int id;
        Employee::tasks thingsToDo;

    public:
        EmployeeImpl(const char* lastname, int id);
        char* getLastname();
        Task_ptr getTask(::CORBA::Short id);
};

#include "EmployeeImpl.h"

EmployeeImpl::EmployeeImpl(const char* lastname, int id)
{
    this->lastname = CORBA::string_dup(lastname);
    this->id = id;
    this->thingsToDo.length(3);

    TaskImpl *t1, *t2, *t3;
    t1 = new TaskImpl("Print all the documents");
    t2 = new TaskImpl("Write the report");
    t3 = new TaskImpl("Make backup");

    this->thingsToDo[0] = Task::_duplicate(t1->_this());
    this->thingsToDo[1] = Task::_duplicate(t2->_this());
    this->thingsToDo[2] = Task::_duplicate(t3->_this());
}

char* EmployeeImpl::getLastname()
{
    return CORBA::string_dup(this->lastname.in());
}

Task_ptr EmployeeImpl::getTask(::CORBA::Short id)
{
    return this->thingsToDo[id-1]._retn();
}

WorkImpl.h および WorkImpl.cpp:

#include "Work.hh"
#include <vector>
#include "EmployeeImpl.h"
using namespace std;

class WorkImpl : public POA_Work
{
    private:
        vector<EmployeeImpl> employees;

    public:
        WorkImpl();
        Employee_ptr getEmployee(::CORBA::Short id);
};

#include "WorkImpl.h"

 WorkImpl::WorkImpl()
 {
    EmployeeImpl ei1(CORBA::string_dup("Doe"), 1);
    EmployeeImpl ei2(CORBA::string_dup("Smith"), 2);
    EmployeeImpl ei3(CORBA::string_dup("Brown"), 3);

    employees.push_back(ei1);
    employees.push_back(ei2);
    employees.push_back(ei3);
 }

Employee_ptr WorkImpl::getEmployee(::CORBA::Short id)
{
    return employees[id]._this();
}

サーバー.cpp:

#include "WorkImpl.h"
#include <omniORB4/CORBA.h>
#include <omniORB4/Naming.hh>
#include <iostream>
using std::cout;
using std::cerr;

int main(int argc, char **argv)
{
 try
 {
  CORBA::ORB_ptr serverORB = CORBA::ORB_init(argc, argv);

  CORBA::Object_var myPOAObj = serverORB->resolve_initial_references("RootPOA");

  PortableServer::POA_var myPOA = PortableServer::POA::_narrow(myPOAObj);
  PortableServer::POAManager_var myManager = myPOA->the_POAManager();
  myManager->activate();

  WorkImpl *work = new WorkImpl();

  try
  {
   CORBA::Object_var nameServiceObj = serverORB->resolve_initial_references("NameService");

   if(!CORBA::is_nil(nameServiceObj))
   {
    CosNaming::NamingContext_ptr namingContext = CosNaming::NamingContext::_narrow(nameServiceObj);
    CosNaming::Name serviceName;
    serviceName.length(1);
    serviceName[0].id = CORBA::string_dup("WorkService");
    namingContext->rebind(serviceName, work->_this());
    cout << "WorkService is running ...\n";
   }

  }catch(CosNaming::NamingContext::NotFound&){
      cerr << "CosNaming::NamingContext::NotFound\n";
  }catch(CosNaming::NamingContext::InvalidName&){
      cerr << "CosNaming::NamingContext::InvalidName\n";
  }catch(CosNaming::NamingContext::CannotProceed&){
      cerr << "CosNaming::NamingContext::CannotProceed\n";
  }

  serverORB->run();

  delete work;
  serverORB->destroy();

  }catch(CORBA::SystemException&){
    cerr << "Caught CORBA::SystemException\n";
  }catch(CORBA::Exception&){
    cerr << "Caught CORBA::Exception  \n";
  }catch(omniORB::fatalException &fe){
    cerr << "Caught omniORB::fatalException\n";
    cerr << "File: " << fe.file() << "\n";
    cerr << "Line: " << fe.line() << "\n";
    cerr << "Msg: " << fe.errmsg() << "\n";
  }catch(...){
    cerr << "Caught unknown exception\n";
  }

   return 0;
}

クライアント.java:

package OtherPackage;

import java.util.*;
import org.omg.CosNaming.*;
import org.omg.CosNaming.NamingContextPackage.*;
import org.omg.CORBA.*;
import java.io.*;
public class Client
{
    public static void main(String [] args)
    {
     try
     {
        org.omg.CORBA.ORB clientORB = org.omg.CORBA.ORB.init(args, null);

        if (clientORB == null)
        {
            System.out.println("Problem while creating ORB");
            System.exit(1);
        }

        org.omg.CORBA.Object objRef = clientORB.resolve_initial_references("NameService");
        NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef);

        Work work = WorkHelper.narrow(ncRef.resolve_str("WorkService"));
        Employee e = work.getEmployee((short)1);
        System.out.println(e.getLastname());

        Task t = e.getTask();
        System.out.println(t.getThingToDo((short)2));

            System.out.println(work.getEmployee((short)2).getThingToDo((short)1));

        }catch(Exception e){ System.out.println(e.getMessage()); }
    }
}

クライアントをコンパイルしようとすると、エラーが発生します。

Client.java:29: getTask(short) in OtherPackage.EmployeeOperations cannot be applied to ()
                Task t = e.getTask();
                          ^
Client.java:30: getThingToDo() in OtherPackage.TaskOperations cannot be applied to (short)
                System.out.println(t.getThingToDo((short)2));
                                    ^
2 errors

どうしたの?そのように書くことは可能ですか?

私が使用したいくつかのコマンド:

Compile (and run) server files (just copy and paste):

g++ -c *.cpp -I$OMNIORB_HOME/include -I$OMNIORB_HOME/include/omniORB4
g++ -c *.cc -I$OMNIORB_HOME/include -I$OMNIORB_HOME/include/omniORB4
g++ -o Server Server.o EmployeeSK.o WorkSK.o WorkImpl.o EmployeeImpl.o TaskImpl.o TaskSK.o -L$OMNIORB_HOME/lib -lomnithread -lomniORB4
./Server -ORBInitRef NameService=corbaloc::localhost:2809/NameService

Compile (and run) client files (just copy and paste):

cd EmployeePackage; javac -cp .. *.java
cd OtherPackage; javac -cp .. *.java

私の全体の例: http://www21.zippyshare.com/v/95586459/file.html

4

2 に答える 2

2

パラメータgetTaskを取るように定義しました:short id

Task getTask(in short id);

ただし、引数なしで呼び出そうとしました:

Task t = e.getTask();

もう 1 つのエラーは、性質が非常に似ています。getThingToDo空のパラメーター リストを持つように定義しました。

string getThingToDo();

...そしてまた、間違った引数で呼び出そうとしました。この場合、次を渡そうとしましたshort:

System.out.println(t.getThingToDo((short)2));

代わりに、次のようにすることをお勧めします。これにより、意図したことが達成されると思います。

final Task t = e.getTask((short) 2);
System.out.println(t.getThingToDo());

... 2 番目の従業員の2 番目のタスクの説明、つまり"Write the report". std::vectorインデックスがゼロであることを忘れないでください。

于 2012-09-09T17:33:58.620 に答える
1

@oldrinbが言ったようにコードを変更しましたが、今はすべて問題ありません(つまり、コンパイル)。

問題は現在適用中です (ロジック?)。クライアントを初めて実行すると、次のように表示されます。

Smith
Print all the documents

どちらが正しい。しかし、クライアントを 2 回目 (および 3 回目など) に実行すると、次のように表示されます。

Smith
null

今どこに問題がありますか?Heres 私の作業コード: http://www9.zippyshare.com/v/46287610/file.html

クライアントを実行するにはcd、Java カタログに移動してコマンドを 実行します。java OtherPackage.Client -ORBInitRef NameService=corbaloc::localhost:2809/NameService

EmployeeImpl.cppを変更しました:

#include "EmployeeImpl.h"

EmployeeImpl::EmployeeImpl(const char* lastname, int id)
{
    this->lastname = CORBA::string_dup(lastname);
    this->id = id;
    this->thingsToDo.length(3);

    TaskImpl *t1, *t2, *t3;
    t1 = new TaskImpl("Print all the documents");
    t2 = new TaskImpl("Write the report");
    t3 = new TaskImpl("Make backup");

    this->thingsToDo[0] = t1->_this();
    this->thingsToDo[1] = t2->_this();
    this->thingsToDo[2] = t3->_this();
}

char* EmployeeImpl::getLastname()
{
    return CORBA::string_dup(this->lastname.in());
}

Task_ptr EmployeeImpl::getTask(::CORBA::Short id)
{
    return Task::_duplicate(this->thingsToDo[id-1]);
}

そして今ではすべてが良さそうです。しかし、それがCORBAの方法で良いかどうかはわかりません.何か提案はありますか?

于 2012-09-10T13:00:12.807 に答える