| DMI Basics | Features Profile | DMI Client Interface | ScriptVar | DMI Server | Using DMI in C++ | DMI with CfgScript | DMI Server Objects | Subclassing | Delegates |
Dynamic Method Invocation (DMI) - is a core ACDK feature for integration
of scripting, middleware and distributed computing, like COM+ and CORBA.
In CORBA or COM an IDL (Interface Definition Language) is used
to describe the communication interfaces of services.
The normal way to connect different language domains - for example
C++ and Java - you
- have to write the interface defintion in the
IDL,
- use a IDL compiler to generate stubs and proxies in Java and
C++ and
- implement the classes in Java/C++ derived from from the
the generated stubs.
DMI uses another aproach:
- Implement the ACDK C++ class or Java class in normal way
- In case of C++ use acdkmc to generate DMI meta information,
in case of Java do nothing.
In IDL you have to use high expensive 'round trip' engineering tools
to keep IDL and language implementation in synchronized state.
With DMI the used language will be used to distill or query the
interface definition, so no such tools are needed.
For some interfaces - like CORBA - a IDL distiller is available
to generate IDL files for the origin DMI server class.
The communication between components in ACDK is over
the Objects methods, whereas every class/object is a
component.
C++ - the implementation language of ACDK - is a strong typed language
and early binding of the components. This has the effect, that at compile
time the types of the communicating objects and the binary interfaces must be
known. The interfaces are static.
This has many advantages:
- Error checks at compile time and not at runtime
- Good performance
But there is also disadvantages:
- Difficult to embed C++ into scripting languages.
- Not possible to explore and call interfaces at runtime
- No generic bridges between middle ware is possible
Most scripting and interpreted languages has more generic interface.
- source code can be loaded at runtime
- Object code can be written at runtime
- The number and types of arguments are checked
at runtime.
The major component technologies COM+ and CORBA provides
both ways of communication:
- static bind calls:
CORBA: static skeleton/proxy
COM+: concrete interfaces
- dynamic bind calls:
CORBA: Dynamic Interface Invocation & Dynamic Skeleton Interface (DII/DSI)
COM+: Interface IDispatch
In COM+ and interface, which supports both ways of communication are called
dual dispatched interfaces.
ACDK provides also two ways to communicate with ACDK objects:
- static bind calls: Normal C++ method calls
- dynamic bind calls: Dynamic Method Invokation (DMI)
Every ACDK class has a DMI interface, defined in the
namespace %nref[acdk::lang::dmi] and
the class acdk::lang::dmi::StdDispatch.
Here an example of usage of this interface:
// static C++ version
RStringBuffer sb = new StringBuffer("Hello");
sb->append("ACDK");
RString erg = sb->toString();
// DMI vesion
RObject sb = StdDispatch::New("acdk/lang/StringBuffer", (const char*)"Hello ");
sb->invoke("append", (const char*)"ACDK");
RString erg = sb->invoke("toString");
|
A mixture of static and dynamic method calls is also possible:
// DMI vesion
RStringBuffer sb = StdDispatch::New("acdk/lang/StringBuffer",
(const char*)"Hello ");
sb->append("ACDK");
RString erg = sb->invoke("toString");
|
Calling a method in C++ uses static overloading:
class AClass
: extends acdk::lang::Object
{
ACDK_WITH_METAINFO(AClass)
public:
void foo(IN(RObject) obj);
void foo(IN(RString) str);
};
RObject obj = new String("asdf");
RAClass acls = new AClass();
acls->foo(obj); // this class void foo(IN(RObject) obj);
|
Calling methods via DMI the arguments types will be evaluated
at runtime. The DMI dispatcher tries to find the best matching
method for the given runtime arguments:
acls->invoke("foo", inOf(obj)); // calls void foo(IN(RString) str);
|
There are 2 sides of the DMI protocols:
DMI Server provides Object functionality in the DMI conforming
way.
- All ACDK C++ Objects.
- CORBA components.
- COM+ components (ActiveX).
- Java Classes.
- ....
DMI clients used this DMI interface to make use of the objects.
Normally DMI client contains also a mapping into the client language.
- ACDK C++.
- Perl.
- Lisp.
- C++-COM clients.
- VBScript/JavaScript.
- Visual Basic.
- Tcl.
- Python.
The client server interfaces can be connected. The advantage of this
connectivity you can access DMI Servers (like a COM component) in
with DMI client (like Perl) without additionally glue-code (Proxy, Stub, etc.)
in a very natural way.
sub require_class($)
{
my ($cls) = @_;
my $cl = acdk::new(\"acdk/lang/ClassLoader\");
$cl->findClass($cls);
}
require_class('acdkx/com/ComObject');
# acdkx/com/ComObject is not an ordinary object
# but a DMI Server implementation which overwrites the standard
# DMI Server methods
$word = acdk::invoke_static('acdkx/com/ComObject', 'New', 'Word.Application');
# access directly the COM-Object
$word->poke('Visible', 1);
$doc = $word->peek('Documents')->add();
$sel = $word->peek('ActiveWindow')->peek('Selection');
# 'TypeText' is not really a acdkx/com/ComObject but
# a method of the Selection option of Word
$sel->TypeText(\"This is \");
$sel->peek('Font')->poke('Bold', 1);
$sel->TypeText(\"ACDK\");
$sel->peek('Font')->poke('Bold', 0);
$sel->TypeText(\" instrumenting Word through acdk_perl\");
acdk::invoke_static('acdk/lang/Thread', 'sleep', 3000);
$word->Quit(0);
|
|