動機
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*型みたいな感じだと思うんですが...