Rules must be observed when passing parameters to a CORBA object
implementation. The type used to pass the parameters of a method signature
is dependent on the Interface Definition List (IDL) type and the directionality
of the parameter (in , inout, out, or return value).
The following
rules for passing these parameters are dictated by CORBA Object Management
Group (OMG) IDL to C++ mapping and must be followed to:
- Ensure the required access authority
- Prevent memory leaks
- Ensure that the allocation and deallocation of memory is performed consistently
- in parameters
- The caller (client) must allocate the input parameters.
The callee (implementation) is restricted to read access. The caller is responsible
for the eventual release of the storage. Primitive types and fixed-length
aggregate types can either be heap allocated or stack allocated. By their
nature, variable-length aggregates cannot be completely stack allocated.
Normally,
a caller uses a _var object to pass non-primitive arguments as input parameters.
The _var class contains an in() method that can be used as additional evidence
that the argument is an input argument..
call opIn(t_var);
call opIn(t_var.in());
- inout parameters
- For inout parameters, the caller provides the
initial value and the callee can change that value. For primitive types and
fixed-length aggregates, this is a straightforward process. The caller provides
the storage and the callee overwrites the storage on return. For variable-length
aggregates, the size of the contained data provided as input might differ
from the size of the contained data provided at output. Therefore, the callee
is required to deallocate any contained input data that is being replaced on
output with callee allocated data. For object references, the caller provides
an initial value. If the callee reassigns the value, the callee must first
release the original input value. The callee assumes or retains ownership
of the returned parameters and must eventually deallocate or release them.
Normally,
a caller uses a _var object to pass non-primitive arguments as inout parameters.
The _var class contains an inout() method that can be used as additional evidence
that the argument is an inout argument.
call opInOut(t_var);
call opInOut(t_var.inout());
- out parameters
- For primitive types and fixed-length aggregate
types, the caller allocates the storage for the out parameter and the callee
sets the value. For variable-length aggregate types, the caller allocates
a pointer and passes it by reference and the callee sets the pointer to point
to a valid instance of the parameter's type. For object references, the caller
allocates storage for the _ptr and the callee sets the _ptr to point to a
valid instance. Because a pointer to an array in C++ must be represented as
a pointer to the array element type, CORBA defines an array_slice type, where
a slice is an array with all the dimensions of the original except the first.
The output parameter is typed as a reference to an array_slice pointer. The
caller allocates the storage for the pointer and the callee updates the pointer
to point to a valid instance of an array_slice. The caller assumes or retains
ownership of the output parameter storage and must eventually deallocate it
or, in the case of object references, release it.
The callee can assume
that the output argument does not have a value. If an output argument contains
an initial value, the value is orphaned and never released. To prevent this
from happening, all of the out parameters are defined in the method signature
with an _out class. The _out class is a special generated class that ensures
that the values are properly released before the callee gets control. The
callee can treat _out objects as if they were the underlying type.
Normally,
a caller uses a _var object to pass non-primitive arguments as out parameters.
The _var class contains an out() method that can be used as additional documentation
that the argument is an out argument.
call opOut(t_var);
call opOut(t_var.out());
- return values
- For primitive types and fixed-length aggregate types,
the caller allocates the storage for the return value and the callee returns
a value for the type. For variable-length aggregate types, the caller allocates
a pointer and the callee returns a pointer to an instance of the type. For
object references, the caller allocates storage for the _ptr and the callee
returns a _ptr that points to a valid object instance. Because a pointer to
an array in C++ must be represented as a pointer to the array element type, the
array_slice type is used for returning array values. The caller allocates
storage for a pointer to the array_slice and the callee returns a pointer
to a valid instance of an array_slice. The caller assumes or retains ownership
of the storage associated with returned values and must eventually deallocate
it or, in the case of object references, release it.
These rules for passing parameters are captured and enforced by the
header files produced when an IDL interface description is compiled. Some
rules cannot be enforced by the bindings. For example, parameters that are
passed or returned as a pointer type (T*) or reference to pointer(T*&)
must not be passed or returned as a null pointer. Memory management responsibilities
cannot be enforced by the bindings. Client (caller) and implementation (callee)
programmers must understand and implement according to these rules.
For
more detailed information on storage management and argument passing, see
the following topics:
- C++ type mapping for argument passing
- Storage management responsibilities for arguments