somClassDispatch

From EDM2
Jump to: navigation, search

somClassDispatch Invokes a method using dispatch method resolution. The somDispatch method is designed to be overridden. The somClassDispatch method is not generally overridden.

For backward compatibility, this method does not take an Environment parameter.

Original Class 
SOMObject

Syntax

boolean somClassDispatch (SOMObject receiver, SOMClass clsObj, somToken retValue, somID methodId, va_list args)

Parameters

receiver (SOMObject) 
A pointer to the object whose class will be used for method resolution by somDispatch.
clsObj (SOMClass) 
A pointer to the class that will be used for method resolution by somClassDispatch.
retValue (somToken) 
The address of the area in memory where the result of the invoked method procedure is to be stored. The caller is responsible for allocating enough memory to hold the result of the specified method. When dispatching methods that return no result (i.e., void), a NULL may be passed as this argument.
methodId (somID) 
A somId identifying the method to be invoked. A string representing the method name can be converted to a somId using the somIdFromString function.
args (va_list) 
A va_list containing the arguments to be passed to the method identified by methodId. The arguments must include a pointer to the target object as the first entry. As a convenience for C and C++ programmers, SOM's language bindings provide a varargs invocation macro for va_list methods (such as somDispatch and somClassDispatch). The example below illustrates this.

Return Code

rc (boolean) 
A boolean representing whether or not the method was successfully dispatched is returned. The reason for this is that somDispatch and somClassDispatch use the function somApply to invoke the resolved method procedure, and somApply requires an apply stub for successful execution. In support of old class binaries SOM does not consider a NULL apply stub to be an error. As a result, somApply may fail. If this happens, then false is returned; otherwise true is returned.

Remarks

somDispatch and somClassDispatch perform method resolution to select a method procedure, and then invoke this procedure on args. The somSelf argument for the selected method procedure (called the target object, below, to distinguish it from the receiver of the somDispatch or somClassDispatch method call) is the first argument included in the va_list, args.

For somDispatch, method resolution is performed using the class of the receiver; for somClassDispatch, method resolution is performed using the argument class, clsObj. Because somClassDispatch uses clsObj for method resolution, a programmer invoking somDispatch or somClassDispatch should assure that the class of the target object is either derived from or is identical to the class used for method resolution; otherwise, a runtime error will likely result when the target object is passed to the resolved procedure. Although not necessary, the receiver is usually also the target object.

The somDispatch and somClassDispatch methods supersede the somDispatchX methods. Unlike the somDispatchX methods, which are restricted to few return types, the somDispatch and somClassDispatch methods make no assumptions concerning the result returned by the method to be invoked. Thus, somDispatch and somClassDispatch can be used to invoke methods that return structures. The somDispatchX methods now invoke somDispatch, so verriding somDispatch serves to override the somDispatchX methods as well.

Example Code

Given class Key that has an attribute keyval of type long and an overridden method for somPrintSelf that prints the value of the attribute (as well as the information printed by SOMObject's implementation of somPrintSelf), the following client code invokes methods on Key objects using somDispatch and somClassDispatch. (The Key class was defined with the callstyle=oidl class modifier, so the Environment argument is not required of its methods.)

#include <key.h>

main()
{
  SOMObject obj;
  long k1 = 7, k2;
  Key *myKey = KeyNew();
  somVaBuf vb;
  va_list push, args;

  somId setId = somIdFromString("_set_keyval");
  somId getId = somIdFromString("_get_keyval");
  somId prtId = somIdFromString("somPrintSelf");

  vb = (somVaBuf)somVaBuf_create(NULL, 0);
  somVaBuf_add(vb, (char *)&myKey, tk_ulong);
  somVaBuf_add(vb, (char *)&k1, tk_long);
  somVaBuf_get_valist(vb, &args);


  /* va_list invocation of setkey and getkey */
  SOMObject_somDispatch(myKey, (somToken *)0, setId, args);
  somVaBuf_get_valist(vb, &args);
  SOMObject_somDispatch(myKey, (somToken *)&k2, getId, args);
  printf("va_list _set_keyval and _get_keyval: %i\n", k2);

  /* varargs invocation of setkey and getkey */
  _somDispatch(myKey, (somToken *)0, setId, myKey, k1);
  _somDispatch(myKey, (somToken *)&k2, getId, myKey);
  printf("varargs _set_keyval and _get_keyval: %i\n", k2);

  /* illustrate somClassDispatch "casting" (use varargs form) */
  printf("somPrintSelf on myKey as a Key:\n");
  _somClassDispatch(myKey, _Key, (somToken *)&obj, prtId, myKey, 0);

  printf("somPrintSelf on myKey as a SOMObject:\n");
  _somClassDispatch(myKey, _SOMObject, (somToken *)&obj, prtId, myKe

  SOMFree(setId);
  SOMFree(getId);
  SOMFree(prtId);
  _somFree(myKey);

  somVaBuf_destroy(vb);
}

This program produces the following output:

va_list _set_keyval and _get_keyval: 7
varargs _set_keyval and _get_keyval: 7
somPrintSelf on myKey as a Key:
{An instance of class Key at address 2005B2F8}
    -- with key value 7
somPrintSelf on myKey as a SOMObject:
{An instance of class Key at address 2005B2F8}

Related

Functions