YAMAGUCHI::weblog

海水パンツとゴーグルで、巨万の富を築きました。カリブの怪物、フリーアルバイター瞳です。

MICO CORBAでの関数への変数の渡し方

動機

CORBAでクライアントがサーバと通信をする際に複数のデータを受け取りたいときに使うTYPE_out型の引数をどう扱っていいか分からなかったので調べてまとめたかった.

前置き

IDLではモジュール,インターフェース,オペレーションというC++で言うところの名前空間,クラス,関数のひな形を最初に作ってやります.

  • test.idl
interface Test {
    struct mydata {
        long id;
        string name;
    }
    typedef sequence<mydata> mydataSeq;
    long search(in long id, out mydataSeq);
}

これをidlコンパイラでパースすると,C++のクラス等が生成されます.おおざっぱに書くと下のような感じ.

  • test.h
class Test : virtual public CORBA::Object {
public:
    virtual ~Test();
    struct mydata {
        mydata();
        ~mydata();
        CORBA::Long id;
        CORBA::String_var name;
    }
    typedef SequenceTmpl<mydata, MICO_TID_DER> mydataSeq;
    typedef TSeqVar< SequenceTmpl< mydata,MICO_TID_DEF> > mydataSeq_var;
    typedef TSeqOut< SequenceTmpl< mydata,MICO_TID_DEF> > mydataSeq_out;
    virtual CORBA::Long search(const CORBA::Long& id, mydataSeq_out results) = 0;
}

実装は?

実際はこの抽象クラスを継承したTest_implクラスみたいなのを実装するわけだけど,このときsearch関数はこんな感じで実装して,こんな感じで使ってみる.

  • クライアント側(呼び出し側)
///Test*型の test;
mydataSeq* data_seq = new mydataSeq;
long id = 10;
test->search(id, mydataSeq);
for (int i = 0; i < n_result; i++)
{
    std::cerr << mydataSeq->name << std::endl;
}
  • サーバ側(search実装)
if (results.ptr() == 0)
    results = new mydataSeq(result_size);

results->length(result_size);

for (int i = 0; i < result_size; i++)
{
    results[i]->name = fetched_name[i];
    results[i]->id = i;
}

適当な例ですがこんな感じで基本的にはTYPE_out型はTYPE型のポインタ的な扱いになるようです.

まとめ

「お前,全然TYPE_var型について書いてねーじゃねーかよ!」と思う人もいるかと思います.すみません,自分分からないんです.なんとなく触ってみた感じこいつもTYPE*型みたいな感じだと思うんですが...

追記

違うCORBAの実装だけど,こんなの見つけました.

この辺の記述を見るとどうやら予想は当たってました.追記するとすれば,「TYPE_out型はユーザが直接触っちゃだめ!」ということでしょう.あくまでそこはデータをやりとりするためのトンネルみたいなもんだと思ってればいいのかな?
TYPE_var型はその為のメモリの確保をちょっとしやすくしましたよ,という話みたいだ.
うーん,相変わらずドキュメントが少ないなぁ.