| DMI Basics | Features Profile | DMI Client Interface | ScriptVar | DMI Server | Using DMI in C++ | DMI with CfgScript | DMI Server Objects | Subclassing | Delegates |
With DmiProxies foreign DMI Servers can implement
ACDK Interfaces and extends existing classes.
As shown so long it is possible to call other objects methods
through DMI, whereas DMI automatically hides the details of the
invocation translation.
In object oriented software development not only functions are
the common exported application interface, but also interfaces.
ACDK provides a mechanism, which makes it possible to implement
an interface with any DMI Server implementations.
Given a native C++ interface:
class MyInterface
ACDK_INTERFACEBASE
{
public:
virtual void callIt() = 0;
};
|
If a script implements this interface it provides a function void callIt()
which can be called through DMI.
If this method is called by the script itself the standard dispatching functionality
of DMI calls the script implementation.
But in the case the script implementation want to provide this interface implementation
a native C++ method (like a Iterator implementation to a Collection function) the native
implementation doesn't know anything about the script implementation. It makes a native
call to callIt().
The solution are native C++ DMI Proxy implementation of the native interface, which
forwards the call to the script implementation.
You can use acdkmc -dmiproxy src/mymodule to generate DMI-Proxy
implementation of the classes an interfaces in src/mymodule.
! |
Due limitation of the acdkmc parser, you must have already compiled a mymodule shared library
which contains the extended metainfo of this module.
The acdkmc loads this extended metainfo to retrieve all information about virtual methods
of this class and their super classes and interfaces.
|
Rules for DMI Proxy:
- DMI Proxy classes should have a default constructor.
The default constructor can also be protected.
- Proxies are only be generated for virtual methods
- don't change visibility (public/private) in derived classes
- In a class, which implements a abstract virtual method from
a interface should not be tagged as foreign.
The pseudo keyword final can be used to mark classes
which should not provide a DMI Proxy:
// for MyClass no DMI Proxy will be generated
final
class MyClass
: extends acdk::lang::Object
{
public:
virtual void foo() { /*...*/ }
};
|
A language, which makes use of the DMI proxies is CfgScript.
Sample Implementation in CfgScript:
class CfgTask
extends acdk.lang.Object
implements Task
{
Task() {}
void callIt() { out.println("CfgTask called"); }
}
|
Sample Implementation in Java:
public class JavaTask
{
/**
Execute the command
@param properties has the same interface like java.util.Properties
*/
public int execute(String cmd, acdk.java.AcdkObject env)
{
if (cmd.equals("sayhello") == true)
{
System.out.println("Hello from Java");
return 0;
}
return 1;
}
}
|
Alternative implementation in Lisp
(defclass LispTask ()
(
(execute :initform
(lamda (cmd env)
(if (cmd 'equals "sayhello")
(progn
(println "Hello from Lisp")
(return 0)
)
(return 1)
)
)
)
)
)
|
! |
This is outdated and must be updated in further version of this document.
|
/* old doesn't work further
RTask javatask = (RTask)Task::getDmiProxy(new ::acdk::java::JavaObject("JavaTask"));
RTask lisptask = (RTask)Task::getDmiProxy(new ::acdk::lisp::LispObject("LispTask"));
javatask->execute("sayhello", System::getProperties());
lisptask->execute("sayhello", System::getProperties());
*/
|
|