| 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.
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);
}
|
For parameter passing the Generic type acdk::lang::dmi::ScriptVar
will be used.
In connection C++ there are some problems with the parameter passing.
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"); .
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 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.
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 calls a static method of an ACDK class.
acdk::lang::dmi::ScriptVar invoke_static(IN(RString) classname, IN(RString) methodname, ScriptVar& arg1, ...);
peek reads an static member field value.
acdk::lang::dmi::ScriptVar peek(IN(RString) membername);
peek_static reads a static member field value.
static acdk::lang::dmi::ScriptVar peek_static(IN(RString) classname, IN(RString) membername);
poke writes a member field value.
void poke(IN(RString) membername, acdk::lang::dmi::ScriptVar& newval);
poke writes a static member field value.
static void poke_static(IN(RString) classname, IN(RString) membername, acdk::lang::dmi::ScriptVar& newval);
|