[Up: C++ mapping]
[Previous: Untyped values] [Next: Unions]

#
Arrays

Arrays are handled somewhat awkwardly in CORBA. The C++ mapping for the declaration of an array is straight forward. Things are getting a bit more complicated when arrays are being passed around as parameters of operations. Arrays are mapped to the corresponding C++ array definition, which allows the definition of statically-initialized data using the array. If the array element is a string or an object reference, then the mapping uses the same type as for structure members. That is, assignment to an array element will release the storage associated with the old value.

      // IDL
      typedef string V[10];
      typedef string M[1][2][3];

      // C++
      V v1; V_var v2;
      M m1; M_var m2;

      v1[1] = v2[1]; // free old storage, copy
      m1[0][1][2] = m2[0][1][2]; // free old storage, copy

In the above example, the two assignments result in the storage associated with the old value of the left-hand side being automatically released before the value from the right-hand side is copied.

Because arrays are mapped into regular C++ arrays, they present special problems for the type-safe `Any` mapping described in 16.14. To facilitate their use with the type `Any`, MICO also provides for each array type a distinct C++ type whose name consists of the array name followed by the suffix `_forany`. Like `Array_var` types, `Array_forany` types allow access to the underlying array type. The interface of the `Array_forany` type is identical to that of the `Array_var` type.

      // IDL
      typedef string V[10];

      // C++
      V_forany v1, v2;
      v1[0] = ...;  // Initialize array

      CORBA::Any any;
      any <<= v1;
      any >>= v2;   // v1 and v2 now have identical contents

Besides the `Array_forany` mapping the CORBA standard also describes a mapping for an array slice. A slice of an array is an array with all the dimension of the original but the first. Output parameters and results are handled via pointers to array slices. The array slice is named like the array itself plus appending the suffix `_slice`. For the declaration of type `M` in the example above, the IDL compiler would generate the following type definition:

      // Generated by IDL compiler, C++
      typedef M M_slice[2][3];

Let's consider the following IDL specification (see also `mico/test/idl/18`):

      // IDL
      // Note: long_arr is an array of fixed length data type
      typedef long long_arr[ 10 ];

      // Note: SS is an array of variable data type
      typedef string SS[ 5 ][ 4 ];

      interface foo {
        SS bar( in SS x, inout SS y, out SS z, out long_arr w );
      };

The implementation of interface `foo` will look like this:

    class foo_impl : virtual public foo_skel
    {
      //...
      SS_slice* bar( const SS ss1, SS ss2, SS_slice*& ss3, long_arr arr )
      {
        //...
        ss3 = SS_alloc();
        SS_slice *res = SS_alloc();
        return res;
      };
    };

Note that the result value of the operation `bar` is a pointer to an array slice. Output parameters where the type is an array to a variable length data type, are handled via a reference to a pointer of an array slice. In order to facilitate memory management with array slices, the CORBA standard prescribes the usage of special functions defined at the same scope as the array type. For the array `SS`, the following functions will be available to a program:

      // C++
      SS_slice *SS_alloc();
      SS_slice *SS_dup( const SS_slice* );
      void SS_free( SS_slice * );

The `SS_alloc` function dynamically allocates an array, or returns a null pointer if it cannot perform the allocation. The `SS_dup` function dynamically allocates a new array with the same size as its array argument, copies each element of the argument array into the new array, and returns a pointer to the new array. If allocation fails, a null pointer is returned. The `SS_free` function deallocates an array that was allocated with `SS_alloc` or `SS_dup`. Passing a null pointer to `SS_free` is acceptable and results in no action being performed.

[Previous: Untyped values] [Next: Unions]
[Up: C++ mapping]