2005/5/10

     
 

Using DMI in C++

artefaktur

| DMI Basics | Features Profile | DMI Client Interface | ScriptVar | DMI Server | Using DMI in C++ | DMI with CfgScript | DMI Server Objects | Subclassing | Delegates |


ACDK DMI can be used in C++ to load and invoke classes at runtime.


Content of this chapter:

   Parameter passing
     Mismatch of passing IN(RString) and OUT(char)
     Use the outOf, inoutOf methods to convert a standard type to corresponding parameter passing types
   The standard Client DMI interface
     New
     invoke
     invoke_static
     peek
     peek_static
     poke
     poke_static



Short Example

  
  using ::acdk::lang::dmi; // uses classes from the DMI 
  
  
  {
    // first the sample code in normal ACDK C++ using 
    // the known classes directly
    RString initvalue = "Hello";

    ::acdk::lang::RStringBuffer sb = new ::acdk::lang::StringBuffer(initvalue);
    sb->append(" ACDK");

    ::acdk::io::RPrintWriter out = System::out;
    RString str = sb->toString();
    RString erg = "String should contain 'Hello ACDK': " + str;
    out->println(erg);
  }
  {
    // the same code using the Dynamic Method Invocation
    RString initvalue = "Hello";

    // create a class acdk::lang::StringBuffer and call the constructur
    // with one argument.
    // the new instance will be assigned to sb
    RObject sb = StdDispatch::New("acdk/lang/StringBuffer", &initvalue);

    // calling a non static method 'append' with one argument
    sb->invoke("append", (const char*)" ACDK");

    // from the class acdk::lang::System get the static member
    // 'out'
    RObject out = StdDispatch::peek_static("acdk/lang/System", "out");
    
    // call from sb the method 'toString'
    RString str = (RString)sb->invoke("toString");
    RString erg = "String should contain 'Hello ACDK': " + str;

    // call from out (which is a PrintWriter) the the method println
    out->invoke("println", &erg);
  }

 Parameter passing

For parameter passing the Generic type  acdk::lang::dmi::ScriptVar will be used.

In connection C++ there are some problems with the parameter passing.

 Mismatch of passing IN(RString) and OUT(char)

An C++ string iterator ("asdf") has the type 'char*'. This will be identified as pointer to a character by the parameter passing mechanism, which results to try to pass one character as OUT or INOUT. Cast your string iterator to a const char* like in:
sb->invoke("append", (const char*)" ACDK");.

 Use the outOf, inoutOf methods to convert a standard type to corresponding parameter passing types

To convert an Object variable to method which expect an OUT or INOUT parameter use the the outOf and inoutOf methods:

class AnClass 
: extends acdk::lang::Object
{
  // ...
  void getAnInteger(OUT(RInteger) intege); 
};

AnClass anclass;
RInteger integer = new Integer(-1);
anclass->invoke("getAnInteger", outOf(integer));

 The standard Client DMI interface


 New

The New call creates a new Object. static acdk::lang::dmi::ScriptVar Object::New(IN(RString) classname, ScriptVar& arg1, ...);
Pramam can be 0 - 7 parameters.

If the class cannot be located in the loaded packages (executable with loaded shared libraries/DLLs) it uses the standard ClassLoader to find package with the class.
See  ClassLoader for more information about loading classes at runtime.
The New call maps to all conforming (non-foreign) public Constructors of the ACDK class.
Sample:

RString initval = "Hallo ACDK";
RObject sb = Object::New("acdk/lang/StringBuffer", &initval);
See also:  acdk::lang::dmi::StdDispatch.


 invoke

The invoke method calls a nonstatic method of an ACDK object.
acdk::lang::dmi::ScriptVar invoke(IN(RString) methodname, ScriptVar& arg1, ...);
In case the called methods returns void, the ScriptVar contains the type UnknownType.
Sample:

RString initval = "Hallo";
RObject sb = Object::New("acdk/lang/StringBuffer", &initval);
sb->invoke("append", (const char*)" ACDK");

 invoke_static

invoke_static calls a static method of an ACDK class.
acdk::lang::dmi::ScriptVar invoke_static(IN(RString) classname, IN(RString) methodname, ScriptVar& arg1, ...);

 peek

peek reads an static member field value.
acdk::lang::dmi::ScriptVar peek(IN(RString) membername);

 peek_static

peek_static reads a static member field value.
static acdk::lang::dmi::ScriptVar peek_static(IN(RString) classname, IN(RString) membername);

 poke

poke writes a member field value.
void poke(IN(RString) membername, acdk::lang::dmi::ScriptVar& newval);

 poke_static

poke writes a static member field value.
static void poke_static(IN(RString) classname, IN(RString) membername, acdk::lang::dmi::ScriptVar& newval);