Jump to content

Using SOM Classes in Client Programs: Difference between revisions

From EDM2
No edit summary
Line 27: Line 27:
==An Example Client Program==
==An Example Client Program==
Following is a C program that uses the class "Hello" (as defined in the Tutorial in Chapter 2). The "Hello" class provides one attribute, "msg", of type string, and one method, "sayHello". The "sayHello" method simply displays the value of the "msg" attribute of the object on which the method is invoked.  
Following is a C program that uses the class "Hello" (as defined in the Tutorial in Chapter 2). The "Hello" class provides one attribute, "msg", of type string, and one method, "sayHello". The "sayHello" method simply displays the value of the "msg" attribute of the object on which the method is invoked.  
 
<PRE>
   #include <hello.h>  /* include the header file for Hello */
   #include <hello.h>  /* include the header file for Hello */


Line 53: Line 53:
         return(0);
         return(0);
   }
   }
 
</PRE>


The C++ version of the foregoing client program is shown below:  
The C++ version of the foregoing client program is shown below:  
 
<PRE>
   #include <hello.xh>  /* include the header file for Hello */
   #include <hello.xh>  /* include the header file for Hello */


Line 81: Line 81:
       return(0);
       return(0);
   }
   }
 
</PRE>


These client programs both produce the output:  
These client programs both produce the output:  

Revision as of 05:15, 3 August 2020

This chapter discusses how to use SOM classes that have already been fully implemented. That is, these topics describe the steps that a programmer uses to instantiate an object and invoke some method(s) on it from within an application program.

Who should read this chapter?

  • Programmers who wish to use SOM classes that were originally developed by someone else will need to know the information in this chapter. These programmers often may not need the information from any subsequent chapters.
  • By contrast, class implementers who are creating their own SOM classes should continue with Chapter 4, "SOM IDL and the SOM Compiler," and Chapter 5, "Implementing Classes in SOM "for complete information on the SOM Interface Definition Language (SOM IDL) syntax and other details of class implementation.

Programs that use a class are referred to as client programs. A client program can be written in C, in C++, or in another language. As noted, this chapter describes how client programs can use SOM classes (classes defined using SOM, as described in Chapter 2, "Tutorial for Implementing SOM Classes" and in Chapter 4, "SOM IDL and the SOM Compiler"and Chapter 5 "Implementing Classes in SOM"). Using a SOM class involves creating instances of a class, invoking methods on objects, and so forth. All of the methods, functions, and macros described here can also be used by class implementers within the implementation file for a class.

Note
"Using a SOM class," as described in this chapter, does not include subclassing the class in a client program. In particular, the C++ compatible SOM classes made available in the .xh binding file can not be subclassed in C++ to create new C++ or SOM classes.

Some of the macros and functions described here are supplied as part of SOM's 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 more convenient for C and C++ programmers to create and use instances of SOM classes. SOM classes can be also used without the C or C++ bindings, however. For example, users of other programming languages 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's interface to SOM. Vendors of other languages may 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 an 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 the IDL interface definition available to the user, and on how the SOM Compiler was invoked when generating bindings.

Usage binding headers automatically include any other bindings upon which they may rely. Client programs not using the C or C++ bindings for any particular class of SOM object (for example, a client program that does not know at compile time what classes it will be using) should simply include the SOM-supplied bindings for SOMObject, provided in the header file "somobj.h" (for C programs) or"somobj.xh" (for C++ programs).

For each task that a user of a SOM class might want to perform, this chapter shows how the task would be accomplished by:

  • a C programmer using the C bindings,
  • a C++ programmer using the C++ bindings, or
  • a programmer not using SOM's C or C++ language bindings.

If neither of the first two approaches is applicable, the third approach can always be used.

An Example Client Program

Following is a C program that uses the class "Hello" (as defined in the Tutorial in Chapter 2). The "Hello" class provides one attribute, "msg", of type string, and one method, "sayHello". The "sayHello" method simply displays the value of the "msg" attribute of the object on which the method is invoked.

   #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 _set_msg on obj with the argument
        * "Hello World Again". This method sets the value of
        * obj's 'msg' attribute to the specified string.
        */
        __set_msg(obj, somGetGlobalEnvironment(), "Hello World Again");

        /* invoke method sayHello on obj. This method prints
         * the value of obj's 'msg' attribute.  */
        _sayHello(obj, somGetGlobalEnvironment());

        _somFree(obj);
        return(0);
   }

The C++ version of the foregoing client program is shown below:

   #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 method _set_msg on obj with the argument
       * "Hello World Again". This method sets the value of
       * obj's 'msg' attribute to the specified string.  */
      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());

      obj->somFree();
      return(0);
   }

These client programs both produce the output:

Hello World Again

Using SOM Classes: the Basics

This section covers the following subjects:

  • Declaring object variables
  • Creating instances of a class
  • Invoking methods on objects
  • Using class objects
  • Compiling and linking

Declaring object variables

When declaring an object variable, an object interface name defined in IDL is used as the type of the variable. The exact syntax is slightly different for C vs. C++ programmers. Specifically,

<interfaceName> obj ; in C programs 

or

<interfaceName> *obj ; in C++ programs 

declares "obj" to be a pointer to an object that has type <interfaceName>. In SOM, objects of this type are instances of the SOM class named <interfaceName>, or of any SOM class derived from this class. Thus, for example,

Animal obj; in C programs 

or

Animal *obj; in C++ programs 

declares "obj" as pointer to an object of type "Animal" that can be used to reference an instance of the SOM class "Animal" or any SOM class derived from "Animal". Note that the type of an object need not be the same as its class; an object of type "Animal" might not be an instance of the "Animal" class (rather, it might be an instance of some subclass of "Animal" - the "Cat" class, perhaps).

All SOM objects are of type SOMObject, even though they may not be instances of the SOMObject class. Thus, if it is not known at compile time what type of object the variable will point to, the following declaration can be used:

SOMObject obj; in C programs 

or

SOMObject *obj; in C++ programs. 

Because the sizes of SOM objects are not known at compile time, instances of SOM classes must always be dynamically allocated. Thus, a variable declaration must always define a pointer to an object.

Note: In the C usage bindings, as within an IDL specification, an interface name used as a type implicitly indicates a pointer to an object that has that interface (this is required by the CORBA specification). The C usage bindings for SOM classes therefore hide the pointer with a C typedef for <interfaceName>. But this is not appropriate in the C++ usage bindings, which define a C++ class for <interfaceName>. Thus, it is not correct in C++ to use a declaration of the form:

<interfaceName> obj ; not valid in C++ programs 

Note: If a C programmer also prefers to use explicit pointers to <interfaceName> types, then the SOM Compiler option -maddstar can be used when the C binding files are generated, and the explicit " *" will then be required in declarations of object variables. (This option is required for compatibility with existing SOM OIDL code. For information on using the -maddstar option, see "Running the SOM Compiler" in Chapter 4, "SOM IDL and the SOM Compiler.")

Users of other programming languages must also define object variables to be pointers to the data structure used to represent SOM objects. The way this is done is programming-language dependent. The header file "somtypes.h" defines the structure of SOM objects for the C language.

Creating instances of a class

For C programmers with usage bindings, SOM provides the <className>New and the <className>Renew macros for creating instances of a class.

These macros are illustrated with the following two examples, each of which creates a single instance of class "Hello":

  obj = HelloNew();
  obj = HelloRenew(buffer);

Using <className> New

After verifying that the <className> class object exists, the <className>New macro invokes the somNew method on the class object. This allocates enough space for a new instance of <className>, creates a new instance of the class, initializes this new object by invoking somDefaultIniton it, and then returns a pointer to it. The <className>Newmacro automatically creates the the class object for <className>, as well as its ancestor classes and metaclass, if these objects have not already been created.

After a client program has finished using an object created using the <className >New macro, the object should be freed by invoking the method somFree on it:

  _somFree(obj);

After uninitializing the object by invoking somDestruct on it, somFree calls the class object for storage deallocation. This is important because storage for an object created using the <className>New macro is allocated by the class of the object. Thus, only the class of the object can know how to reclaim the object's storage. object for storage deallocation.

Using <className> Renew

After verifying that the <className> class object exists, the <className>Renew macro invokes the somRenew method on the class object. <className>Renew is only used when the space for the object has been allocated previously. (Perhaps the space holds an old uninitialized object that is not needed anymore.) This macro converts the given space into a new, initialized instance of <className> and returns a pointer to it. The programmer is responsible for ensuring that the argument of <className>Renew points to a block of storage large enough to hold an instance of class <className>. The SOM method somGetInstanceSize can be invoked on the class to determine the amount of memory required. Like <className>New, the <className>Renew macro automatically creates any required class objects that have not already been created.

Hint: When creating a large number of class instances, it may be more efficient to allocate at once enough memory to hold all the instances, and then invoke <className>Renew once for each object to be created, rather than performing separate memory allocations.

Using <className> NewClass

The C and C++ usage bindings for a SOM class also provide static linkage to a <className>NewClass function that can be used to create the class object. This can be useful if the class object is needed before its instances are created.

For example, the following C code uses the function HelloNewClass to create the "Hello" class object. The arguments to this function are defined by the usage bindings, and indicate the version of the class implementation that is assumed by the bindings. (For more detail on creation of classes, see the later section, "Creating a class object.") Once the class object has been created, the example invokes the method somGetInstanceSize on this class to determine the size of a "Hello" object, uses SOMMalloc to allocate storage, and then uses the HelloRenew macro to create ten instances of the "Hello" class:

   #include <hello.h>
   main()
   {
   SOMClass helloCls; /*  A pointer for the Hello class object */
   Hello objA[10];    /*  an array of Hello instances */
   unsigned char *buffer;
   int i;
   int size;

   /* create the Hello class object:  */
   helloCls =  HelloNewClass(Hello_MajorVersion, Hello_MinorVersion);

   /* get the amount of space needed for a Hello instance:
    * (somGetInstanceSize is a method provided by SOM.) */
   size =  _somGetInstanceSize(helloCls);
   size = ((size+3)/4)*4;  /* round up to doubleword multiple */

   /* allocate the total space needed for ten instances: */
   buffer =  SOMMalloc(10*size);

   /* convert the space into ten separate Hello instances: */
   for (i=0; i<10; i++)
       objA[i] = HelloRenew(buffer+i*size);
   ...
   ...
   /* Uninitialize the objects and free them */
   for (i=0; i<10; i++)
     _somDestruct(objA[i],0,0);
   SOMFree(buffer);
   }

When an object created with the <className>Renew macro is no longer needed, its storage must be freed using the dual to whatever method was originally used to allocate the storage. Two method pairs are typical:

  • For example, if an object was originally initialized using the <className>New macro, then, as discussed previously, the client should use the somFree method on it.
  • On the other hand, if the program uses the SOMMalloc function to allocate memory, as illustrated in the example above, then the SOMFree function must be called to free the objects' storage (because SOMFree is the dual to SOMMalloc). Before this is done, the objects in the region to be freed should be deinitialized by invoking the somDestruct method on them. This allows each object to free any memory that may have been allocated without the programmer's knowledge. (The somFree method also calls the somDestruct method.)


Note
In the somDestruct method call above, the first zero indicates that memory should not be freed by the class of the object (that is, the programmer will do it explicitly). The second zero indicates that the class of the object is responsible for overall control of object uninitialization. For further discussion, see Section 5.5, "Initializing and Uninitializing Objects," in Chapter 5, "Implementing Classes in SOM."

For C++ programmers with usage bindings, instances of a class <className> can be created with a new operator provided by the usage bindings of each SOM class. The new operator automatically creates the class object for <className>, as well as its ancestor classes and metaclass, if they do not yet exist. After verifying the existence of the desired class object, the new operator then invokes the somNewNoInit method on the class. This allocates memory and creates a new instance of the class, but it does not initialize the new object. Initialization of the new object is then performed using one of the C++ constructors defined by the usage bindings. (For further discussion, see Section 5.5 "Initializing and Uninitializing Objects," in Chapter 5, "Implementing Classes in SOM.") Two variations of the new operator require no arguments. When either is used, the C++ usage bindings provide a default constructor that invokes the somDefaultInit method on the new object. Thus, a new object initialized by somDefaultInit would be created using either of the forms:

new <className>

new <classname>()

For example:

  obj = new Hello;
  obj1 = new Hello();


For convenience, pointers to SOM objects created using the newoperator can be freed using the delete operator, just as for normal C++ objects (or, the somFree method could be used):

 delete obj;
 obj1->somFree;


When previously allocated space will be used to hold a new object, C++ programmers should use the somRenew method, described below. C++ bindings do not provide a macro for this purpose.

somNew and somRenew
C and C++ programmers, as well programmers using other languages, can create instances of a class using the SOM methods somNew and somRenew, invoked on the class object. As discussed and illustrated above for the C bindings, the class object must first be created using the <className>NewClass procedure (or, perhaps, using the somFindClass method-see the section "Using class objects," to follow later in this chapter).

The somNew method invoked on the class object creates a new instance of the class, initializes the object using somDefaultInit, and then returns a pointer to the new object. For instance, the following C example creates a new object of the "Hello" class.

   #include <hello.h>
   main()
   {
     SOMClass helloCls;   /* a pointer to the Hello class */
     Hello obj;           /* a pointer to an Hello instance */
     /* create the Hello class  */
     helloCls = HelloNewClass(Hello_MajorVersion, Hello_MinorVersion);
     obj = _somNew(helloCls); /* create the Hello instance */
   }

An object created using the somNew method should be freed by invoking the somFree method on it after the client program is finished using the object.

The somRenew method invoked on the class object creates a new instance of a class using the given space, rather than allocating new space for the object. The method converts the given space into an instance of the class, initializes the new object using somDefaultInit, and then returns a pointer to it. The argument to somRenew must point to a block of storage large enough to hold the new instance. The method somGetInstanceSize can be used to determine the amount of memory required. For example, the following C++ code creates ten instances of the "Hello" class:

   #include <hello.xh>
   #include <somcls.xh>
   main()
   {
     SOMClass *helloCls; // a pointer to the Hello class
     Hello *objA[10]  //  an array of Hello instance pointers
     unsigned char *buffer;
     int i;
     int size;

    // create the Hello class object
    helloCls =  HelloNewClass(Hello_MajorVersion, Hello_MinorVersion);

    // get the amount of space needed for a Hello instance:
    size = helloCls-> somGetInstanceSize();
    size = ((size+3)/4)*4;  // round up to doubleword multiple

    // allocate the total space needed for ten instances
    buffer =  SOMMalloc(10*size);

    // convert the space into ten separate Hello objects
    for (i=0; i<10; i++)
       objA[i] = helloCls-> somRenew(buffer+i*size);

    // Uninitialize the objects and free them
    for (i=0; i<10; i++)
       objA[i]-> somDestruct(0,0);
    SOMFree(buffer);
   }

The somNew and somRenew methods are useful for creating instances of a class when the header file for the class is not included in the client program at compile time. (The name of the class might be specified by user input, for example.) However, the <className>New macro (for C) and the new operator (for C++) can only be used for classes whose header file is included in the client program at compile time.

Objects created using the somRenew method should be freed by the client program that allocated it, using the dual to whatever allocation approach was initially used. If the somFree method is not appropriate (because the method somNew was not initially used), then, before memory is freed, the object should be explicitly deinitialized by invoking the somDestruct method on it. (The somFree method calls the somDestruct method. Refer to the previous C example for Renew for an explanation of the arguments to somDestruct.)

Invoking methods on objects

This topic describes the general way to invoke methods in C/C+ + and in other languages, and then presents subtopics for more specialized situations.

Making typical method calls

For C programmers with usage bindings: To invoke a method in C, use the macro:

_<methodName> (receiver, args)

(that is, an underscore followed by the method name). Arguments to the macro are the receiver of the method followed by all of the arguments to the method. For example:

  _foo(obj, somGetGlobalEnvironment(), x, y)


This invokes method "foo" on "obj" (the remaining arguments are arguments to the method "foo"). This expression can be used anywhere that a standard function call can be used in C.

Required arguments

In C, calls to methods defined using IDL 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 specified by CORBA, and is used to pass environmental information between a caller and a called method. For example, it is used to return exceptions. (For more information on how to supply and use the Environment structure, see the later section entitled "Exceptions and error handling.")

In the IDL definition of a method, by contrast, 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, even though it is never explicitly specified in IDL. For this reason, it is called an implicit method parameter.) For example, if a method is defined in a .idl file with two parameters, as in:

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


then, with the C usage bindings, the method would be invoked with four arguments, as in:

  intvar = _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", above.

If the IDL specification of the method includes a context specification, then the method has an additional (implicit) context parameter. Thus, when invoking the method, this argument must follow immediately after the Environment pointer argument. (None of the SOM-supplied methods require context arguments.) The Environment and context method parameters are prescribed by the CORBA standard.

If the IDL specification of the class that introduces the method includes the callstyle=oidl modifier, then the (Environment*) and context arguments should not be supplied when invoking the method. That is, the receiver of the method call is followed immediately by the arguments to the method (if any). Some of the classes supplied in the SOMobjects Toolkit (including SOMObject, SOMClass, and SOMClassMgr) are defined in this way, to ensure compatibility with the previous release of SOM. The System Object Model Programming Reference specifies for each method whether these arguments are used.

If you use a C expression to compute the first argument to a method call (the receiver), you must use an expression without side effects, because the first argument is evaluated twice by the _<methodName> macro expansion. In particular, a somNew method call or a macro call of <className>New can not be used as the first argument to a C method call, because doing so would create two new class instances rather than one.

Following the initial, required arguments to a method (the receiving object, the Environment, if any, and the context, if any), you enter any additional arguments required by that method, as specified in IDL. For a discussion of how IDL in/out/inout argument types may to C/C++ data types, see the topic "Parameter list" in Chapter 4, "SOM IDL and the SOM Compiler."

Short form vs long form

If a client program uses the bindings for two different classes that introduce or inherit two different methods of the same name, then the _<methodName> macro described above (called the short form) will not be provided by the bindings, because the macro would be ambiguous in that circumstance. The following long form macro, however, is always provided by the usage bindings for each class that supports the method:

<className>_<methodName> (receiver, args)

For example, method "foo" supported by class "Bar" can be invoked as:

 Bar_foo(obj, somGetGlobalEnvironment(), x, y)     (in C)

where "obj" has type "Bar" and "x" and "y" are the arguments to method "foo".

In most cases (where there is no ambiguity, and where the method is not a va_list method, as described in the subsequent subtopic "Using 'va_list' methods"), a C programmer may use either the short or the long form of a method invocation macro interchangeably. However, only the long form complies with the CORBA standard for C usage bindings. If you wish to write code that can be easily ported to other vendor platforms that support the CORBA standard, use the long form exclusively. The long form is always available for every method that a class supports. The short form is provided both as a programming convenience and for source code compatibility with release 1 of SOM.

In order to use the long form, a programmer will usually know what type an object is expected to have. If this is not known, but the different methods have the same signature, the method can be invoked using name-lookup resolution, as described in a following subtopic of this section.

For C++ programmers with usage bindings: To invoke a method, use the standard C++ form shown below:

obj-><methodName> (args)

where args are the arguments to the method. For instance, the following example invokes method "foo" on "obj":

  obj->foo(somGetGlobalEnvironment(), x, y)

Required arguments

All methods introduced by classes declared using IDL (except those having the SOM IDL callstyle=oidl modifier) have at least one parameter-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. For more information on how to supply and use the Environment structure, see the later section entitled "Exceptions and error handling."

The Environment pointer is an implicit parameter; in the IDL definition of a method, the Environment pointer is not explicitly listed as a parameter to the method. For example, if a method is defined in IDL with two explicit parameters, as in:

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


then the method would be invoked from C++ bindings with three arguments, as in:

  intvar = obj->foo(somGetGlobalEnvironment(), x, y);


where "obj" is the object responding to the method and "x" and "y" are the arguments corresponding to "c" and "f", above.

If the IDL specification of the method includes a context specification, then the method has a second implicit parameter, of type context, and the method must be invoked with an additional context argument. This argument must follow immediately after the Environment pointer argument. (No SOM-supplied methods require context arguments.) The Environment and context method parameters are prescribed by the CORBA standard.

If the IDL specification of the class that introduces the method includes the callstyle=oidl modifier, then the (Environment *) and context arguments should not be supplied when the method is invoked. Some of the classes supplied in the SOMobjects Toolkit (including SOMObject, SOMClass, and SOMClassMgr) are defined in this way, to ensure compatibility with the previous release of SOM. The System Object Model Programming Reference specifies for each method whether these arguments are used.

Following the initial, required arguments to a method (the receiving object, the Environment, if any, and the context, if any), you enter any additional arguments required by that method, as specified in IDL. For a discussion of how IDL in/out/inout argument types map to C/C++ data types, see the topic "Parameter list" in Chapter 4, "SOM IDL and the SOM Compiler."

For non-C/C++ programmers: To invoke a static method (that is, a method declared when defining an OIDL or IDL object interface) without using the C or C++ usage bindings, a programmer can use the somResolve procedure. The somResolve procedure takes as arguments a pointer to the object on which the method is to be invoked and a method token for the desired method. It returns a pointer to the method's procedure (or raises a fatal error if the object does not support the method). Depending on the language and system, it may be necessary to cast this procedure pointer to the appropriate type; the way this is done is language-specific.

The method is then invoked by calling the procedure returned by somResolve (the means for calling a procedure, given a pointer to it, is language-specific), passing the method's receiver, the Environment pointer (if necessary), the context argument (if necessary) and the remainder of the method's arguments, if any. (See the section above for C programmers; the arguments to a method procedure are the same as the arguments passed using the long form of the C-language method-invocation macro for that method.)

Using somResolve requires the programmer to know where to find the method token for the desired method. Method tokens are available from class objects that support the method (via the method somGetMethodToken), or from a global data structure, called the ClassData structure, corresponding to the class that introduces the method. In C and C++ programs with access to the definitions for ClassData structures provided by usage bindings, the method token for method methodName introduced by class className may be accessed by the following expression:

<className>ClassData.<methodName >

For example, the method token for method "sayHello"introduced by class "Hello" is stored at location HelloClassData.sayHello, for C and C++ programmers. The way method tokens are accessed in other languages is language-specific.

As an example of using offset resolution to invoke methods from a programming language other than C/C++, one would do the following to create an instance of a SOM Class X in Smalltalk:

1.Initialize the SOM run-time environment, if it has not previously been initialized, using the somEnvironmentNew function.

2.If the class object for class X has not yet been created, use somResolve with arguments SOMClassMgrObject (returned by somEnvironmentNew in step 1) and the method token for the somFindClass method, to obtain a method procedure pointer for the somFindClass method. Use the method procedure for somFindClass to create the class object for class X: Call the procedure with arguments SOMClassMgrObject, the result of calling the somIdFromString function with argument "X", and the major and minor version numbers for class X (or zero). The procedure returns the class object for class X.

3.Use somResolve with arguments representing the class object for X (returned by somFindClass in step 2) and the method token for the somNew method, to obtain a method procedure pointer for method somNew. (The somNew method is used to create instances of class X.)

4.Call the method procedure for somNew (using the method procedure pointer obtained in step 3) with the class object for X (returned by somFindClass in step 3) as the argument. The procedure returns a new instance of class X.

In addition to somResolve, SOM also supplies the somClassResolve procedure. Instead of an object, the somClassResolve procedure takes a class as its first argument, and then selects a method procedure from the instance method table of the passed class. (The somResolve procedure, by contrast, selects a method procedure from the instance method table of the class of which the passed object is an instance.) The somClassResolve procedure therefore supports casted method resolution. See the System Object Model Programming Reference for more information on somResolve and somClassResolve.

If the programmer does not know at compile time which class introduces the method to be invoked, or if the programmer cannot directly access method tokens, then the procedure somResolveByName can be used to obtain a method procedure using name-lookup resolution, as described in the next section.

If the signature of the method to be invoked is not known at compile time, but can be discovered at run time, use somResolve or somResolveByName to get a pointer to the somDispatch method procedure, then use it to invoke the specific method, as described below under "Method name or signature not known at compile time."

Accessing Attributes

Using 'va_list' methods

Using name-lookup method resolution

A name-lookup example

Obtaining a method's procedure pointer

           Offset resolution
           Name-lookup method resolution 

Method name or signature not known at compile time

           Dispatch-function method resolution 

Using class objects

Getting the class of an object

Creating a class object

           Using Renew or somRenew
           Using NewClass
           Using somFindClass or somFindClsInFile 

Referring to class objects

Compiling and linking

Language-neutral Methods and Functions

Generating output

Getting information about a class

Getting information about an object

Methods

Functions

Debugging

Checking the validity of method calls

Exceptions and error handling

Exception declarations

Standard exceptions

       The Environment
       Setting an exception value
       Getting an exception value
       Example 
   Memory management
   SOM manipulations using somId's