[ Previous | Next | Contents | Glossary | Home | Search ]
Ultimedia Services Version 2 for AIX: Programmer's Guide and Reference

Calling Methods from C and C++

One library exists for Ultimedia Services: the libUMSobj.a library. All include files are located in the UMS installation directory.

Note: The UMS installation directory is /usr/lpp/UMS6000 for AIX Version 3.2.x systems and /usr/lpp/UMS for AIX Version 4 or later systems.

The header file naming conventions are:

.h C objects
.xh C++ objects

Programs that use a class are referred to as client programs. This section describes how client programs can use SOM classes. Using a SOM class involves creating instances of a class, calling methods on objects, and so on. All of the methods, functions, and macros described here can also be used by class implementors within the class implementation file.

Some of the macros and functions described here are supplied as part of the SOM C and C++ usage bindings. These bindings are functions and macros defined in header files to be included in client programs. The usage bindings make it convenient for C and C++ programmers to create and use instances of SOM classes. However, SOM classes can be used without the C or C++ bindings. For example, you use other programming languages you can use SOM classes, and C and C++ programmers can use a SOM class without using its language bindings. The language bindings simply offer a more convenient programmer interface to SOM. Vendors of other languages can also offer SOM bindings; check with your language vendor for possible SOM support.

To use the C or C++ bindings for a class, a client program must include a header file for the class (using the #include preprocessor directive). For a C language client program, the file ClassFileStem.h must be included. For a C++ language client program, the file ClassFileStem.xh must be included. The SOM compiler generates these header files from the IDL interface definition. The header files contain definitions of the macros and functions that make up the C or C++ bindings for the class. Whether the header files include bindings for the class's private methods and attributes (in addition to the public methods and attributes) depends on how the SOM compiler is started when generating the header files.

Programmers not using the C or C++ bindings for any particular class (for example, a client program that does not know at compile time which classes it is using) should obtain the SOMobjects Developer's Toolkit, product number 96F8648, available from the Order Center at 1-800-342-6672.

To learn more about calling methods from C and C++, see:

For introductory information, see Using Ultimedia Services Objects.

Example Programs

The following C and C++ example client programs show how users of a SOM class can perform tasks.

The following is a C program that uses the class Hello defined in a Hello.h include file. The Hello class provides one attribute, msg, of type string, and one method, sayHello. The sayHello method displays the value of the msg attribute of the object on which the method is called.

#include <Hello.h> /* include the header file for Hello */
int main(int argc, char *argv[])
{
        /* declare a variable (obj) that is a 
        * pointer to an instance of the Hello class: */
        Hello obj;
        /* create an instance of the Hello class
        * and store a pointer to it in obj: */
        obj = HelloNew();
        /* invoke method Hello_set_msg on obj with the argument
        * Hello World Again . */
        Hello_set_msg(obj, somGetGlobalEnvironment(), "Hello World               Again" );
        /* invoke method sayHello on obj. */
        Hello_sayHello(obj, somGetGlobalEnvironment());
        return(0);
}

The C++ version of the preceding client program follows:

#include <Hello.xh> /* include the header file for Hello */
int main(int argc, char *argv[])
{
        /* declare a variable (obj) that is a 
        * pointer to an instance of the Hello class: */
        Hello *obj;
        /* create an instance of the Hello class
        * and store a pointer to it in obj: */
        obj = new Hello;
        /* invoke set_msg on obj with the argument
        * Hello World Again */
        obj-> set_msg(somGetGlobalEnvironment(), "Hello World               Again" );
        /* invoke method sayHello on obj. This method prints
        * the value of obj's 'msg' attribute. */
        obj-> sayHello(somGetGlobalEnvironment());
        return(0);
}

Declaring Object Variables

For C and C++ programmers, the following syntax declares obj to be a pointer to an instance of ClassName (or any derived class):

ClassName *obj;
 (in C++ programs)
ClassName obj;
 (in C programs)

For example,

Hello *obj; 
(in C++ programs)
Hello obj;
 (in C programs)

Declares obj to be a pointer to an instance of the Hello class (or any class derived from it). In other words, obj is a pointer to an object of type Hello. Note that the type of an object does not have to be the same as its class; an object of type Hello might not be an instance of the Hello class (it might be an instance of a subclass of Hello instead).

Creating Instances of a Class

The following sections describe how to create instances of a class for C and C++ programmers.

C Programmers

SOM provides the ClassNameNew and the ClassNameRenew macros for creating instances of a class. (Use of the Renew macro requires the AIX Version 4 SOMobjects Base Toolkit Programmer's Reference Manual.)

The New macro creates a single instance of class Hello:

obj = HelloNew();

The ClassNameNew macro allocates enough space for a new instance of ClassName; creates a new, initialized class instance; and returns a pointer to it. The ClassNameNew macro automatically creates the class object for ClassName, as well as its ancestor classes and metaclass if needed.

An object created using the ClassNameNew macro needs to be freed after the client program is finished using the object by calling the somFree method. See the following example:

_somFree(obj);

C++ Programmers

SOM recognizes the new operator, just as in standard C++, using the following form:

new ClassName

For example:

obj = new Hello;

The new operator allocates enough space for an instance of ClassName; creates a new, initialized class instance; and returns a pointer to it. The new operator automatically creates the class object for ClassName, as well as its ancestor classes and metaclass if needed.

SOM objects created using the new operator should be freed using the delete operator, as with C++ objects. For example:

delete obj;

Calling Methods

Method calls in C require at least two arguments: a pointer to the receiving object (the object responding to the method) and a value of type Environment. The Environment data structure is used to pass environmental information between a caller and a called method; for example, it is used to return exceptions.

By contrast, in the IDL definition of a method, the receiver and the environment pointer are not listed as parameters to the method. (Unlike the receiver, the environment pointer is considered a method parameter (Environment), although it is never explicitly specified in IDL. For this reason, it is called an implicit method parameter.) For example, if a method for the object Bar is defined in an .idl file with two parameters as follows:

int foo (in char c, in float f);

The method is called in C with four arguments as follows:

intvar = Bar_foo(obj, somGetGlobalEnvironment(), x, y);

Where obj is the object responding to the method, and x and y are the arguments corresponding to c and f in the preceding example.

If you use a C expression to compute the first parameter to a method call (the receiver), you must use an expression without side effects because the first parameter is evaluated twice by the ClassName_MethodName macro expansion. In particular, a ClassNameNew macro call cannot be used as the first parameter to a C method call because doing so creates two new class instances rather than one.

Sequences and Strings

IDL defines two template types not found in C and C++. These are sequence and string. A sequence is a one-dimensional array with two characteristics: maximum size and length. Sequences are specified as follows:

sequence <simple-type[,positive-int-const] 

Where simple-type specifies any valid IDL type, and the optional positive-int-const is a constant expression that specifies the maximum size of the sequence.

In SOM's C and C++ bindings, sequences are mapped onto structs with the following members:

unsigned long _maximum
unsigned long _length
simple-type  *_buffer

Where simple-type is the specified type of the sequence. The _maximum member designates the size of storage allocated for the sequence, and the _length member designates the number of values contained in the _buffer member. For bounded sequences (those declared with the optional positive-int-const value), it is an error to set the _length or _maximum members to a value larger than the specified bound sequence.

Before a sequence is passed as an in or inout parameter, the _buffer member must point to an array of elements of the appropriate type, and the _length member must contain the number of elements to pass. If the parameter is passed as inout, the _maximum member is used to define the length of the array available at _buffer. Upon return, the _length member is set to the number of elements copied into _buffer. When a sequence is passed as an out parameter or received as a return value, the method procedure allocates the storage for _buffer, the _length member contains the number of elements returned, and the _maximum member contains the number of elements allocated. The client is responsible for subsequently freeing the memory at _buffer.

C and C++ programs using SOM's language bindings can refer to sequences as:

_IDL_Sequence_type

Where type is the effective type of the sequence members.

A string is similar to a sequence of type char. It can contain all possible 8-bit quantities except NULL. Strings are specified as follows:

string [<positive-int-const> ]

Where the optional positive-int-const specifies the maximum size for a bounded string. Strings returned as out parameters are allocated by the procedure method and the client is responsible for subsequently freeing the string.

in, out, and inout Parameter Typing

IDL method parameters are required to have directional attributes of in, out, or inout indicating whether the parameter is being passed from the client to server (in), from server to client (out), or both directions (inout). Method procedures must have addressability to parameters with a directional attribute of out or inout. Therefore, for all IDL types (except arrays), C and C++ clients must pass an address of the variable of that type (or the value of a pointer to that variable).

For arrays, C and C++ clients must pass the address of the first element of the array. For example, the SOM IDL method declaration:

short method1(in char c, out float f) 

Has a procedure signature of:

SOM_Scope short SOMLINK method1(char c, float *f)

For C and C++clients, if a method has an out parameter of type unbounded string or unbounded sequence, then the storage for the string or the _buffer member of the sequence must be allocated by the method. It is then the responsibility of the client program to free the storage when it is no longer needed. Similarly, if the return type of a method is an unbounded string, sequence, or array, then the storage is allocated automatically and the client is responsible for freeing it.


[ Previous | Next | Contents | Glossary | Home | Search ]