For each method introduced or overridden by the class, the implementation template includes a stub procedure-a procedure that is empty except for an initialization statement, a debugging statement, and possibly a return statement. The stub procedure for a method is preceded by any comments that follow the method's declaration in the IDL specification.
For method "sayHello" above, the SOM Compiler generates the following prototype of the stub procedure:
SOM_Scope void SOMLINK sayHello(Hello somSelf, Environment *ev)
The "SOM_Scope" symbol is defined in the implementation header file as either "extern" or "static," as appropriate. The term "void" signifies the return type of method "sayHello". The "SOMLINK" symbol is defined by SOM; it represents the keyword needed to link to the C or C++ compiler, and its value is system-specific. Using the "SOMLINK" symbol allows the code to work with a variety of compilers without modification.
Following the "SOMLINK" symbol is the name of the procedure that implements the method. If no functionprefix modifier has been specified for the class, then the procedure name is the same as the method name. If a functionprefix modifier is in effect, then the procedure name is generated by prepending the specified prefix to the method name. For example, if the class definition contained the following statement:
functionprefix = xx_;
then the prototype of the stub procedure for method "sayHello" would be:
SOM_Scope void SOMLINK xx_sayHello(Hello somSelf, Environment *ev)
The functionprefix can not be
<classname>_
since this is used in method invocation macros defined by the C usage bindings.
Following the procedure name is the formal parameter list for the method procedure. Because each SOM method always receives at least one argument (a pointer to the SOM object that responds to the method), the first parameter name in the prototype of each stub procedure is called somSelf. (The macros defined in the implementation header file rely on this convention.) The somSelf parameter is a pointer to an object that is an instance of the class being implemented (here, class "Hello") or an instance of a class derived from it.
Unless the IDL specification of the class included the callstyle=oidl modifier, then the formal parameter list will include one or two additional parameters before the parameters declared in the IDL specification: an (Environment *ev) input/output parameter, which permits the return of exception information, and, if the IDL specification of the method includes a context specification, a (Context *ctx) input parameter. These parameters are prescribed by the CORBA standard. For more information on using the Environment and Context parameters, see the section entitled "Exceptions and error handling" in Chapter 3, "Using SOM Classes in Client Programs," and the book The Common Object Request Broker: Architecture and Specification, published by Object Management Group and X/Open.
The first statement in the stub procedure for method "sayHello" is the statement:
/* HelloData *somThis = HelloGetData(somSelf); */
This statement is enclosed in comments only when the class does not introduce any instance variables. The purpose of this statement, for classes that do introduce instance variables, is to initialize a local variable (somThis) that points to a structure representing the instance variables introduced by the class. The somThis pointer is used by the macros defined in the "Hello" implementation header file to access those instance variables. (These macros are described below.) In this example, the "Hello" class introduces no instance variables, so the statement is commented out. If instance variables are later added to a class that initially had none, then the comment characters can be removed if access to the variable is required.
The "HelloData" type and the "HelloGetData" macro used to initialize the somThis pointer are defined in the implementation header file. Within a method procedure, class implementers can use the somThis pointer to access instance data, or they can use the convenience macros defined for accessing each instance variable, as described below.
To implement a method so that it can modify a local copy of an object's instance data without affecting the object's real instance data, declare a variable of type <className>Data (for example, "HelloData") and assign to it the structure that somThis points to; then make the somThis pointer point to the copy. For example:
HelloData myCopy = *somThis; somThis = &myCopy;
Next in the stub procedure for method "sayHello" is the statement:
HelloMethodDebug("Hello", "sayHello");
This statement facilitates debugging. The "HelloMethodDebug" macro is defined in the implementation header file. It takes two arguments, a class name and a method name. If debugging is turned on (that is, if global variable SOM_TraceLevel is set to one in the calling program), the macro produces a message each time the method procedure is entered. (See the next Chapter 3, "Using SOM Classes in Client Programs," for information on debugging with SOM.)
Debugging can be permanently disabled (regardless of the setting of the SOM_TraceLevel setting in the calling program) by redefining the <className>MethodDebug macro to be SOM_NoTrace(c,m) following the #include directive for the implementation header file. (This can yield a slight performance improvement.) For example, to permanently disable debugging for the "Hello" class, insert the following lines in the hello.c implementation file following the line "#include hello.ih" (or "#include hello.xih," for classes implemented in C++):
#undef HelloMethodDebug #define HelloMethodDebug(c,m) SOM_NoTrace(c,m)
The way in which the stub procedure ends is determined by whether the method is a new or an overriding method.
If a classinit modifier was specified to designate a user-defined procedure that will initialize the "Hello" class object, as in the statement:
classinit = HInit;
then the implementation template file would include the following stub procedure for "HInit", in addition to the stub procedures for Hello's methods:
void SOMLINK HInit(SOMClass *cls) { }
This stub procedure is then filled in by the class implementer. If the class definition specifies a functionprefix modifier, the classinit procedure name is generated by prepending the specified prefix to the specified classinit name, as with other stub procedures.