| DMI Basics | Features Profile | DMI Client Interface | ScriptVar | DMI Server | Using DMI in C++ | DMI with CfgScript | DMI Server Objects | Subclassing | Delegates |
How to implement own Objects, which can
be called via DMI clients.
The sources of DMI-able ACDK C++-Object are
normal C++ classes with following conditions:
- Classes has to be derived from the ACDK class
acdk::lang::Object or from ::acdk::lang::InterfaceBase
(using ACDK_INTERFACEBASE)
- Sources can contain C++ code, which
is not part of of the ACDK DMI type system.
- ACDK classes can contain super classes, functions, members
which are not part of the ACDK DMI type system
but they should have the 'foreign' attribute
to avoid errors/warnings from the acdkmc meta compiler.
- The directory structure of the sources should reflect
the namespaces: The directory ./src/com/company should
contain classes in the namespace com::company.
- The name of the shared library should reflect the
contained namespaces (or part of it).
See also ClassLoader.
- In one package/shared library namespace parts
should be unambiguously to avoid problems with
linker.
- In each directory/namespace an header with the same
name of the right part of the namespace should be created.
./src/com/company/company.h. This header should contain
includes, which needed before other includes.
- Although not really required, it is strongly recommended
to keep the naming style guides (namespace with all lower
case letters, classes with first upper case letter).
#ifndef com_company_MyClass_h
#define com_company_MyClass_h
#include <acdk.h> // common header
#include "Config.h" // defines dll export macro
// see Config.h's in standard acdk package
#include "company.h" // standard includes for this namespace
// may be empty but needed for acdkmc
namespace com {
namespace company {
// forward declaration of MyClass, RMyClass,
// MyClassArray, RMyClassArray
ACDK_DECL_CLASS(MyClass);
class ACDK_COM_COMPANY_PUBLIC /* defined in Config.h */ MyClass
: extends acdk::lang::Object // has to derived indirect or direct from Object
, implements acdk::lang::Comparable
{
ACDK_WITH_METAINFO(MyClass) // standard dmi interface
// mc generates meta info for this class
protected:
public:
// used by ClassLoader (Class::forName("com/company/MyClass")->newInstance())
// If Extended Metainfo is available, this method is superflous, because the
// ClassLoader also can use the public no-args constructor.
static RObject create_instance() { new MyClass(); }
foreign int internal_val; // foreign tags type, method or member as unknown to meta compiler
int ival; // availabe via peek/poke
static RString sval // available via static_peek/static_poke
foreign const char* internal_ptr; // meta compiler always ignore unknown
// types, foreign avoids waring of acdkmc
MyClass();
RString foo(int i); // available via DMI invoke
int operator+(IN(RString) s); // available via dmi (invoke("operator_pl", mystr))
// the method compareTo is implemented for the Comparable
// interface. This can be tagged as foreign, because a valid
// DMI proxy for this method is already provided by the
// Comparable interface.
foreign int compareTo(IN(RObject) o);
};
#endif //com_company_MyClass_h
|
- Basic types:
- void
- bool
- char (1 byte character)
- uc2char (2 byte unicode character)
- uc4char (4 byte unicode character)
- byte (it is unsigned char)
- short (16 bit signed short)
- int (32 bit signed integer)
- jlong (64 bit signed integer)
- float (32 bit float)
- double (64 bit float)
- Enumerations, which are declared (not necessary defined)
in the same header.
- Reference type to ACDK classes.
Addionally the types can have additionally
attributes:
IN(type), OUT(type), INOUT(type), BYVAL(type).
See also: Types.
! |
The meta compiler acdkmc should always executed with a directory
as argument, to generate Metainfo for all header of one namespace/directory.
|
acdkmc collects all meta information in 2 C++ source
files.
// files
./src/com/company/MyClass.h
./src/com/company/MyClass.cpp
$ACDKHOME/bin/acdkmc src/com/company
This will generate additionally files:
./src/com/company/company_metainf_base.cpp
./src/com/company/company_metainf/company_metainf_ext.cpp
See also: man acdkmc.
! |
On windows platforms the metacompiler may also be named acdkmc_d.exe or
acdkmc_r.exe for debug/release version.
|
In case of many ACDK classes ./src/com/company directory the
*_metainf_ext.cpp files will split into multiple files.
The *_metainf_base.cpp has to be linked into the same shared library
or executable
as the original C++ classes. It contains the core class definitions
of the ACDK Objects. They are used by the acdk ClassLoader, the
garbage collecting routines and in some situations (arrays) for
gathering information about derivation.
The *_metainf_ext.cpp contains the DMI stubs.
In case the ACDK Objects mainly should be used
via DMI and/or the library only contains a few
ACDK DMI Objects this sources can be linked directly
into the library/executable of the C++ classes.
It is also possible to link all *_metainf_ext.cpp files
into a separate shared library. In this case the name
of the shared library has to follow the rules:
- The library name must be the fully qualified name
(namespace and class name) or left side parts of
of the fully qualified name.
- this name must be appended with _metainf
- The shared library has to stored in the $ACDKHOME/bin
directory.
For our example above valid shared library names are:
- libcom_company_MyClass_metainf.so (unix)
- com_company_MyClass_metainf_d.dll (windows debug version)
- com_company_MyClass_metainf_r.dll (windows release version)
- libcom_company_metainf.so (unix)
- com_company_metainf_d.dll (windows debug version)
- com_company_metainf_r.dll (windows release version)
In this case the *_metainf[.so|.dll] will be automatically
loaded by the class loader if an object will be addressed
via DMI.
See also: ClassLoader.
ACDK C++ classes can be derived from ACDK C++ classes
with Metainfo without define itself Metainfo.
It is possible to write ACDK classes without ACDK_WITH_METAINFO.
class MyClass : extends acdk::lang::Object
{
// no ACDK_WITH_METAINFO
...
};
But there are some limits:
If you derive your class from a class and a interface the
static methods clazzInfo(); and GetClass() cannot be resolved
correctly. Therefore you can use the Macro DECL_ACDK_DEFAULT_METACLASS().
ACDK_DECL_CLASS(MySpecialMap);
class MySpecialMap
: extends acdk::lang::Object
, implements acdk::util::Map
{
// if requested meta info, use the meta info from acdk::util::Map
// GetClass does return the Class from Map.
DECL_ACDK_DEFAULT_METACLASS(Map)
public:
//
};
|
Another conflict situation is if a class with meta info
uses another class without meta info:
// class without meta info
ACDK_DECL_CLASS(PureClass);
ACDK_DECL_CLASS(ClassWithMeta);
class ClassWithMeta
: extends Object
{
ACDK_WITH_METAINFO(ClassWithMeta);
public:
// ...
foreign RPureClass myMember;
foreign void setPClass(IN(RPureClass) other);
};
|
If in a class with Metainfo fields, argument or return types are used, with itself
has no Metainfo, these fields/methods has to be marked with the pseudo keyword
foreign . For these fields/methods no Metainfo will be generated.
ACDK uses C structures containing detailed information
of a class with its member and function with detailed
argument types.
The structures are defined in acdk_core/src/acdk/lang/dmi/ClazzInfo.h
(see also acdk::lang::dmi::ClazzInfo).
Additionally interfaces for dynamic invocations are defined in
acdk_core/src/acdk/lang/dmi/StdDispatch.h.
See also:
The DMI interface is not only used to make C++ Objects
available to various scripting languages and component
architectures, but it is also used to enable foreign
object/components to any other DMI clients.
To enable foreign object to be callable via DMI normally
an Proxy-Class for such an foreign Object will be implemented
into ACDK C++. For example acdk::perl::PerlObject is
an DMI able Object for all Perl classes. acdk::java::JavaObject
is a wrapper to Java objects ( acdk::java::JavaObject),
acdkx::com::ComObject is a Proxy
for COM-Objects.
Each these Proxy classes forwards an obj->invoke("methodName")
to the underlying object. The implementation of these proxy classes
does not implement the invoke(), peek(), etc. but a few methods
defined in acdk::lang::dmi::StdDispatch.
Extended features, like a ClassLoader and script implemented interfaces is provided by
the CfgScript language.
|