Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2038188
  • 博文数量: 414
  • 博客积分: 10312
  • 博客等级: 上将
  • 技术积分: 4921
  • 用 户 组: 普通用户
  • 注册时间: 2007-10-31 01:49
文章分类

全部博文(414)

文章存档

2011年(1)

2010年(29)

2009年(82)

2008年(301)

2007年(1)

分类: C/C++

2008-10-10 19:02:52

一、简单基本数据类型(Simple Basic Types)

TAO支持以下简单基本数据类型(%TAO_ROOT%/tao/Basic_Types.h):

IDL

C++

boolean

CORBA::Boolean

char

CORBA::Char

octet

CORBA::Octet

short

CORBA::Short

unsigned short

CORBA::UShort

long

CORBA::Long

unsigned long

CORBA::ULong

long long

CORBA::LongLong

unsigned long long

CORBA::ULongLong

wchar

CORBA::WChar

float

CORBA::Float

double

CORBA::Double

long double

CORBA::LongDouble

    以上各简单基本类型对应的C++类型只是对应平台上基本类型的typedefJava虚拟机能够在各平台上保证统一的数据长度的实现原理),编写应用程序时,

为了保证程序的可移植性,应尽量使用CORBA命名空间中的类型标识。此外,需要注意:在上面的所有类型中,没有C++基本类型byte(被Octet取代)、

int(被Long取代)。

二、复杂基本数据类型(Complex Basic Types

    除简单基本数据类型外,TAO还支持以下复杂基本数据类型:

IDL

C++

string

CORBA::TAO_String_Manager(%TAO_ROOT%/tao/Managed_Types.h)

wstring

CORBA::TAO_WString_Manager(%TAO_ROOT%/tao/Managed_Types.h)

any

CORBA::Any(%TAO_ROOT%/tao/AnyTypeCode/Any.h)

    其中两种String类型在使用时需要注意:

    1、应该尽量使用TAO提供的(也是CORBA规范规定的)如下字符串操作函数:

 

     char *  string_alloc(ULong len);

     char *  string_dup(const char *);

     void    string_free(char *);

     WChar * wstring_alloc(ULong len);

     WChar * wstring_dup(const WChar *);

     void    wstring_free(WChar *);


    用它们来进行字符串操作,以提高系统的可移植性。


    2(w)string_alloc/(w)string_dup后必须调用(w)string_free来释放分配的资源,为了避免忘记(w)string_free带来的麻烦,有些情况下,可以考虑使用

      String_var类型(String_varString类对应的智能指针类,除了TAO本身支持的智能指针类型外,tao_idl在生成代码时会自动为每个Object添加一个

      对应的var类型)。

    3(w)string_alloc(n)会分配n+1字符(不是字节)空间。

      以下是一个简单的字符串操作的例子:

 

      #include

 

      #include

      using namespace std;

 

      int main() {

          char * p = CORBA::string_alloc(5); // 分配6个字符,不是6个字节

          strcpy(p, "Hello"); // 把"Hello"复制到p所指定的字符串里面

 

          cout << p << endl;

 

          CORBA::string_free(p);

 

          CORBA::String_var s = CORBA::string_dup("World");

          cout << s.in() << endl;

 

          return 0;

    }

    注:如果编译该程序时遇到困难,请在阅读完本系列的第五篇文章后再来测试该程序(下同)。

 

      CORBA::AnyWindows开发中常用的VARIANT类型相当,可以在其中存入任意其他类型的数据,但Any更具有面向对象的风格。在Windows应用中向VARIANT写入信息

时需要先设置写入的数据类型,而从中读出数据时往往需要用switch进行判断,相比之下Any的使用就简单多了,可以通过<=操作符来向Any类型变量写入信息,而通过>=操作符

Any变量中读出信息。与从VARIANT中解析数据不同的是,由于重载的>=操作符返回的是一个表示转换成功或者失败的标志,因此,总是使用if...else而不是switch来对解析结

果进行判断。下面是一个使用Any的例子:

 

    #include

 

    #include

    using namespace std;

 

    int main() {

          CORBA::Any a;

          CORBA::Octet o;

          CORBA::Long l;

 

          a <<= CORBA::Long(1); // a 中现在含有了CORBA::Long type类型的值1

          if (a >>= l) {

                cout << "Long: " << l << endl;

          } else {

                cout << "Unknown value." << endl;

          }

 

          a <<= CORBA::Any::from_octet(65); // a 中现在含有了CORBA::Octet 类型的值64

 

          if (a >>= CORBA::Any::to_octet(o)) {

                cout << "Octet: " << o << endl;

          } else {

                cout << "Unknown value." << endl;

          }

 

          return 0;

    }

    

    注:滥用Any类型将对程序的处理性能造成影响。

 

    此外,CORBA规范还规定了一种不太常用的数据类型:CORBA::Fixed,它是一种特殊的浮点类型,在构造fixed类型变量时必须指定两个参数:

总位数(不含小数点)与精度,而CORBA::Fixed则提供了多种从其它基本类型构造Fixed类型的方法,甚至可以从字符串类型构造一个Fixed类型变

量。但是,目前TAO尚不支持Fixed类型。

三、构造类型(Constructed Types

    除了上面的基本类型外,我们还可以在idl中使用structsequenceunionarray等几种构造类型

·        struct

    structC语言中的struct基本上是等价的,其中只能包含变量定义,不能定义方法,对定义的变量进行初始化,或定义union型变量。

·        sequence

    sequenceSTL中的vector比较类似,可以用它来存储相同类型的变量,并且可以“自由”扩充,因此,sequence往往可以在传递

   “变长”参数时发挥重要作用经过idl处理,sequence会被映射成相应的类。下面举一个sequence的例子:

    1、首先,定义如下的idl文件:

     typedef sequence StrSeq;

      将其存为strseq.idl,并在控制台下对其进行编译,命令如下:

     tao_idl.ext strseq.idl

      编译后,将得到一个名为

        strseq.idl  strseqC.cpp  strseqC.h  strseqC.inl  strseqS.cpp  strseqS.h  strseqS.inl

      的文件;

2、   新建一控制台工程,并在主文件中添加如下代码

 

     #include "strseqC.h"

 

     #include

      using namespace std;

 

      int main() {

          const char * values[] = { "first", "second", "third", "fourth" };

          StrSeq myseq; // 生成一个空队列

          // 生产4个空的字符串

          myseq.length(4);

          for (CORBA::ULong i = 0; i < myseq.length(); i++)

              myseq[i] = values[i]; // 深度复制

          // 打印当前队列内容

          for (CORBA::ULong j = 0; j < myseq.length(); j++)

              cout << "myseq[" << j << "] = \"" << myseq[j].in() << "\"" << endl;

          cout << endl;

          // 改变队列的第二个元素(为第二个元素分配空间)

          myseq[1] = CORBA::string_dup("second element");

          // 截断到三个元素

          myseq.length(3); // 分配第四个元素的内存

          // 增长到五个元素(增加两个空字符串)

          myseq.length(5);

          // 初始化追加元素

          myseq[3] = CORBA::string_dup("4th");

          myseq[4] = CORBA::string_dup("5th");

          // 打印所有元素

          for (CORBA::ULong k = 0; k < myseq.length(); k++)

            cout << "myseq[" << k << "] = \"" << myseq[k].in() << "\"" << endl;

 

          return 0;

   }

·        union

      idl中的union类型与C++中的union不是等价的,它实际上被映射成了对应的class,同时在使用上与C++中的union也有极大区别。

    以下面的idl为例:


   union U switch (char) {

   case 'L':

       long long_mem;

   case 'c':

   case 'C':

       char char_mem;

   default:

       short short_mem;

   };

 

   其意义可以解释为:

       类型U可以用于存放三种类型的值:Long型、Char型、Short型,可以分别用long_memchar_memshort_mem取出这些值。

   当使用一个Long型变量初始化该union变量时,类型标志为L(或者反过来,当类型标志为L时,可以在其中存放一个Long型的值);

   当用一个Char型变量初始化该union变量时,类型标志为c或者C;当用一个Short型初始化该union变量时,类型标志为其它值。

   在使用union类型时需要特别注意:不要尝试将类型标志设置为一种类型(通过_d方法),而用另一种类型去初始化它;

   或者,反过来,用一种类型去初始化它,然后又尝试将类型标志修改为其它值。

   下面是一个使用上述idl定义的例子:

 

    #include

    using namespace std;

 

    #include

 

    union U switch (char) {

    case 'L':

        long long_mem;

    case 'c':

    case 'C':

        char char_mem;

    default:

        short short_mem;

    };


    int main() {

        U my_u; // 'my_u' 还没有被初始化

        // my_u._d('c');

        my_u.long_mem(99); //激活 long_mem

        assert(my_u._d() == 'L'); // 校验鉴别器

        assert(my_u.long_mem() == 99); // 校验数值

        // my_u._d('c');

        cout << my_u.char_mem() << endl;

    }

    

    当union中还包括其它变长类型时,情况将变得很复杂,但使用上并没有太大差异。

·        array

     array并不是一个idl所使用的关键字,它表示的是普通定长数组,它被映射成C++代码时也是一个普通的定长数组,因此,其用法比较简单。

    下面是一个使用arrayidl的例子:

 

    typedef float FloatArray[4];

 

    typedef string StrArray[15][10];

    struct S {

          string s_mem;

          long l_mem;

    };

 

    typedef S StructArray[20];

 

    相关测试代码如下:

 

    #include

    using namespace std;


    typedef float FloatArray[4];

 

    typedef string StrArray[15][10];

    struct S {

          string s_mem;

          long l_mem;

    };

 

    typedef S StructArray[20];


    int main() {

        FloatArray my_f = { 1.0, 2.0, 3.0 };

        my_f[3] = my_f[2];

        StrArray my_str;

        my_str[0][0] = CORBA::string_dup("Hello"); // Transfers ownership

        my_str[0][1] = my_str[0][0]; // Deep copy

        StructArray my_s;

        my_s[0].s_mem = CORBA::string_dup("World"); // Transfers ownership

        my_s[0].l_mem = 5;

    }


阅读(3260) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~