Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Advanced CORBA Programming wit C++ - M. Henning, S. Vinoski.pdf
Скачиваний:
64
Добавлен:
24.05.2014
Размер:
5 Mб
Скачать

IT-SC book: Advanced CORBA® Programming with C++

The get_compact_typecode operation removes all type and member names from a type code. The repository ID and alias information are preserved. The operation is useful mainly to strip a type code of excess baggage before sending it to another address space. get_compact_typecode is of interest mainly to implementers of services such as the Event Service. In addition, CORBA 2.3 ORBs will most likely transmit type codes in their minimal form anyway, so you should have no need to call this operation unless you are building a specialized application, such as a protocol bridge.

16.6 Type Code Constants

As you saw in Section 16.4, we can use the Any::type member function to extract the type code from an Any value. In addition, the CORBA specification requires an ORB to make type code constants available to the application.

16.6.1 Constants for Built-In Types

For built-in types, an ORB header file contains type code constants for types in the CORBA namespace:

namespace CORBA {

 

// ...

 

const CORBA::TypeCode_ptr _tc_null = ...;

 

const CORBA::TypeCode_ptr _tc_void = ...;

 

const CORBA::TypeCode_ptr _tc_short = ...;

 

const CORBA::TypeCode_ptr _tc_ushort = ...;

 

const CORBA::TypeCode_ptr _tc_long = ...;

 

const CORBA::TypeCode_ptr _tc_ulong = ...;

 

const CORBA::TypeCode_ptr _tc_float = ...;

 

const CORBA::TypeCode_ptr _tc_double = ...;

 

const CORBA::TypeCode_ptr _tc_boolean = ...;

 

const CORBA::TypeCode_ptr _tc_char = ...;

 

const CORBA::TypeCode_ptr _tc_octet = ...;

 

const CORBA::TypeCode_ptr _tc_any = ...;

 

const CORBA::TypeCode_ptr _tc_TypeCode = ...;

 

const CORBA::TypeCode_ptr _tc_Object = ...;

// Unbounded

const CORBA::TypeCode_ptr _tc_string = ...;

const CORBA::TypeCode_ptr _tc_longlong = ...;

 

const CORBA::TypeCode_ptr _tc_ulonglong = ...;

 

const CORBA::TypeCode_ptr _tc_longdouble = ...;

 

const CORBA::TypeCode_ptr _tc_wchar = ...;

// Unbounded

const CORBA::TypeCode_ptr _tc_wstring = ...;

// ...

 

}

 

Each constant is a pseudo-reference to the corresponding type code. For example, _tc_ulong is a reference to the type code whose TCKind value is tk_ulong. All the type code constants denote type codes without parameters, with the exception of _tc_string, _tc_wstring, and _tc_Object. For strings, the constants denote

626

IT-SC book: Advanced CORBA® Programming with C++

unbounded strings. The _tc_Object constant describes the type Object. For example, we can call the show_TC function as follows:

show_TC(CORBA::_tc_Object);

The output from this is

interface Object (IDL:omg.org/CORBA/Object:1.0)

The type code constants are generated for all built-in and predefined types. For example, the TypeCode interface defines the Bounds exception, so there is a type code constant called CORBA::TypeCode::_tc_Bounds that describes this exception.

Keep in mind that the type code constants are object references. This means that you cannot compare them directly. For example, the following code is in error (even though it may compile):

CORBA::Any a = ...; // ...

CORBA::TypeCode_ptr tcp = a.type(); // Get type code from a

if (tcp == CORBA::_tc_boolean) // Undefined behavior!

...;

switch (tcp) {

// Also undefined behavior!

case CORBA::_tc_boolean:

 

// ...

 

};

 

This code contains two errors because it attempts to compare object references using ==. Depending on how your ORB implements the C++ mapping, this code may compile, but the behavior is completely undefined because it is illegal to compare object references directly.

Neither can we use _is_equivalent for this comparison:

CORBA::Any a = ...;

 

// ...

// Get type code

CORBA::TypeCode_ptr tcp = a.type();

if (tcp->_is_equivalent(CORBA::_tc_boolean))

// Error!

...;

 

The call to _is_equivalent will not compile because TypeCode is a pseudo-object. As you saw in Section 7.7, pseudo-objects do not implicitly inherit from CORBA::Object and therefore support none of the operations defined for

CORBA::Object, such as is_equivalent.

627

IT-SC book: Advanced CORBA® Programming with C++

The only way to compare type codes is to use equal or equivalent:

CORBA::Any a = ...;

 

// ...

// Get typecode from a

CORBA::TypeCode_ptr tcp = a.type();

if (tcp->equal(CORBA::_tc_boolean))

// Well defined in 2.3

...;

if (tcp->equivalent(CORBA::_tc_boolean)) // Well defined

...;

Never assign a type code constant to a _var reference. If you do, the result is undefined:

CORBA::TypeCode_var tcv = CORBA::_tc_boolean; // Disaster!

The generated type code constants are just that, constants, and must not be released.

16.6.2 Constants for User-Defined Types

The IDL compiler also generates type code constants for user-defined types. The constants are generated at the same scope as the point of the definition of the corresponding IDL type. For example, if we link against the stub code for the climate control system, we can use constants such as CCS::_tc_AssetType and

CCS::Thermostat::_tc_BtData:

show_TC(CCS::_tc_AssetType); show_TC(CCS::Thermostat::_tc_BtData);

You can use type code constants for user-defined types in the same way as the constants for built-in types. For example:

CORBA::Any a = ...; // ...

CORBA::TypeCode_var tcv = a.type(); // Get type code from a

if (tcv->equal(CCS::_tc_AssetType)) {

//It's an asset number...

}else if (tcv->equal(CCS::Thermostat::_tc_BtData)) {

//It's a BtData structure...

}else if (tcv->equivalent(CCS::_tc_AssetType)) {

//It's an asset number or an alias for it...

}else if (tcv->equivalent(CCS::Thermostat::_tc_BtData)) {

//It's a BtData structure or an alias for it...

}

Keep in mind, though, that equality comparison for type definitions may not give the correct answer because of the inability of the C++ mapping to control the TCKind value when inserting a value into an Any (see Section 15.4). This means that in the

628

IT-SC book: Advanced CORBA® Programming with C++

preceding example, the comparison against _tc_AssetType with equal is likely to fail because even if the Any contains an asset number, the type code will likely be _tc_ulong instead (at least if the value was inserted into the Any using the C++ mapping). Of course, comparison with equivalent will succeed.

16.7 Type Code Comparison for Type any

As mentioned in Section 15.4, aliases present special problems for insertion into and extraction from type Any. The C++ mapping maps an IDL typedef to a corresponding C++ typedef, and that makes it impossible to precisely control the type code when you are inserting an aliased type into an Any. In addition, this behavior raises the question of how to distinguish between aliases of the same underlying type for the purposes of extraction.

16.7.1 Controlling Alias Information for Insertion into Type Any

Consider again the example from Section 15.4:

module CCS {

ModelType;

typedef string

typedef string

LocType;

// ...

 

};

 

As you saw in Section 15.4, insertion of a value of type ModelType or LocType into an Any results in the Any's type code indicating string and losing the aliasing information. Depending on your application, this behavior may not be important. However, you may want to distinguish between aliases on the receiving end, and that requires the ability to control the type code for an Any for insertion.

The overloaded Any::type member function permits you to control the aliasing information for a value of type Any:

ModelType model = CORBA::string_dup("Select-A-Temp"); CORBA::Any a;

a < <= model; // Sets type code to string a.type(CCS::_tc_ModelType); // Sets type code to ModelType

The type modifier changes the type code of an Any to the type code passed as the argument. In the preceding example, after inserting the model string, we explicitly set the type code to ModelType by calling the type modifier. This technique ensures that the Any carries the correct aliasing information.

629