| Basic Types | Enum Types | Object Types | Array Types | Interface Types | Exception Types | Member Types | Method Types | Namespace Types | Foreign Types |
Methods are function bound to a ACDK interface or class.
Inteface methods, which has to overwritten by
the derived classes are pure virtual:
class LegalAcdkClass
: extends acdk::lang::Object
{
public:
virtual void method() = 0;
};
|
// ...
virtual void method();
|
// ...
static void method();
|
The default argument passing in ACDK methods is:
- basic types (int, float, char, etc.) by value
- enum by value
- classes and interfaces by reference ('R'-objects)
- arrays by reference (is also a 'R'-object)
IDL languages used by DCOM and CORBA supports enhanced
parameter declarations:
The parameter will be passed from the caller to the callee.
This is also the default behaviour if the parameter has not
passing tag.
For performance reason it is recomented to tag all
Object IN parameter with IN attribute.
// ...
void foo(IN(RStringBuffer) buffer, int len)
{
buffer = new StringBuffer(); // caller not be effected, RStringBuffer isn't changed
buffer->append("asdf"); // caller be effected.
len = 42; // caller not be effected
}
// is equivalent to
//void foo(RStringBuffer buffer, int len);
void use_foo()
{
RStringBuffer sb = new StringBuffer("");
RStringBuffer sbs = sb;
int value = 1000;
foo(sb, value);
//value == 1000 && sb == sbs
// sb->toString() == "ACDK"
}
|
If an parameter has no or IN tag, the parameter can also
passed as stack variable:
// ...
void foo(IN(RStringBuffer) sb)
{
}
void use_foo()
{
StringBuffer sb(100); // on stack
foo(&sb); // legal for none, IN and BYVAL
}
|
The parameter will be passed from the caller:
// ...
void foo(OUT(RStringBuffer) buffer, OUT(int) len)
{
// buffer is unitialized here
buffer = new StringBuffer(1024);
// buffer is now initialed;
buffer->append("ACDK");
len = buffer->length();
}
RString use_foo()
{
RStringBuffer sb;
int len;
foo(sb, len);
System::out->println("Buffer is [" + sb->toString() + "] len = " + len);
return sb->toString();
}
|
The OUT parameter behaviour may differs in different context:
if the foo() call is a local inprocess call the OUT parameter works the same
like INOUT parameter - which means, the value given to foo(OUT(RStringBuffer), OUT(int) len) will be visible
by foo() -, in distributed computing the parameter are unitialized.
! | You cannot pass stack object as OUT-Parameter. |
An INOUT parameter is a combination of IN and OUT. A value will transfered from the caller
to the callee and back.
void redimStringBuffer(INOUT(RStringBuffer) sb, INOUT(int) size)
{
if (sb->capacity() > size)
return;
size += size % 1024;
RStringBuffer newnsb = new StringBuffer(size);
newnsb->append(sb->toString());
sb = newsb;
}
void useRedimStringBuffer()
{
RStringBuffer sb = new StringBuffer("ACDK");
int size = 1353;
redimStringBuffer(sb, size);
// sb changed
// sb contains "ACDK"
// size == 2048
}
|
! | You cannot pass stack object as INOUT-Parameter. |
! |
The BYVAL / BYREF will be evaluated only if used in context
of method remoting. Calling a method locally with BYVAL argument,
the values still will be transfered in the default way (by value
for basic types and by reference for object types).
|
Objects normally passed by reference. The BYVAL parameter tag
transfers the object by value. This means, the value will be
copied. This works only for Objects which fullfills following
conditions
- Object supports serialization and
- Object has metainfo
Value will be copied from caller to callee.
The OUT paramter will be copied.
Will mostly has the same effect as normal parameter passing by reference,
but the value will be copied twice.
A sample for exception declaration:
//
RObject set(int index, IN(RObject) obj) THROWS1(RIndexOutOfBoundsException);
// this will be expandet to on some platforms to
RObject set(int index, IN(RObject) obj) throw( RIndexOutOfBoundsException, RThrowable );
// some compiler doesn't support bugfree exception declarations, to it simply expands to:
RObject set(int index, IN(RObject) obj);
|
Following important point has to be regarded:
- In ACDK exceptions are used as reference type (like in Java), so
the 'R'Class type has to be declared in the throw delcarations
- In C++ the caller of a function, which declares possible thrown exception,
are not forced to handle or declare them itself. But if an exception
will thrown by a function, which are are not declared in throw()
(if any) the process will normally terminate.
For this reason the RThrowable - the base of all ACDK exception - will be
declared at the end of the throw-list.
Return values can also be tagged with IN or OUT attributes.
In both cases the method must not return references from stack,
but only members of an class or static values.
class AClass
: extends acdk::lang::Object
{
public:
RObject _instance;
IN(RObject) foo()
{
RObject obj = new String("asdf");
return obj; // !!!! Illegal
}
OUT(RObject) foo()
{
return _instance; // legal
}
};
|
Tagging return values with the IN parameter only has performance
effects in ACDK.
Return values, which are tagged with the OUT attribute will also
return the value by reference in DMI. The caller of the method must
ensure, that the returned value may not used longer, than the called
class instance lifes.
In DMI client, where types must mapped and in all remote DMI server,
return values must not be tagges as OUT value.
See also: ACDK Pseudo Keywords.
|