corba:short describes 16-bit Lisp integers.
This can cause confusion: when is a vector allowed or required? when is a list allowed or required?
The general rule is: if an IDL operation expects a parameter that is a sequence, either a vector or a list may be passed to that operation.
If an IDL operation returns a sequence parameter, it may be either a vector or a list. ORBLink guarantees that if the invocation was remote then the returned sequence value will be a vector, not a list.
Consider the following interface named I defined in module M:
module M {
interface I { attribute long a1;
readonly attribute string a2;}
}
When compiled via corba:idl three classes are created in the Lisp:
module M { //We are reopening the module M
interface K {;};
interface J (I, K) {;};
}
When compiled, the Lisp classes corresponding to J will have the following inheritance structure:
(setq j-serv (make-instance 'M:J-servant :a1 3958810))The value of the attribute a1 of j-serv can be retrieved via:
(op:a1 j-serv) ----> 3958810The value of the attribute can be changed via:
(setf (op:a1 j-serv) -3) (op:a1 j-serv) ---> -3The readers and writers can also be invoked on proxies. However, the initarg cannot be used for a proxy.
If foo is not declared to return void and has no out arguments, it returns a single value.
If foo is declared to return out arguments then they are returned as multiple values after whatever values foo would have returned without those out arguments.
The first argument to op:foo is the object on which it is invoked. The remaining arguments are the parameters of the operation. Consider the following IDL:
module M {
interface optest {
void testvoid (in long a);
long testlong (in string b);
long testmultiple (in string b, out char c);
void testvoidmultiple (out char c1, out string s, out float f3);
};
};
Suppose that m is an object of type M:optest.
Then an invocation sequence might look like:
(op:testvoid m -100000)
--->[No values returned]
(op:testlong m "hello")
--->599934
(op:testmultiple m "goodbye")
---> 3000 #\G
(multiple-value-bind (a b c) ;Get the returned values
(op:testvoidmultiple m)
(list "The values returned are:" a b c))
---> ("The values returned are" #\Y "hurdle" 1.87)
Everything that "looks like a method" in Lisp is mapped to the op package, notably struct member accessors, union member accessors,
attribute accessors, and so on.
module M {
struct S {long foo; string fum;};};
You can create a new instance of the class M:S via
(setq struct (m:s :foo 300 :fum "test")) ---> #< M:S :FOO 300 :FUM "TEST"> (op:foo struct) ---> 300 (setf (op:fum struct) "passed") ---> "passed" (op:fum struct) ---> "passed"
module M { interface IU
{ union V switch (long) {
case 3: string foo;
case 5: long fum;};};};
The name of the corresponding Lisp class is M:IU/V. (The "/" is a scoping separator).
You can create a union with label 3 and value "echo" in the foo member via:
(setq u (M:IU/V :foo "echo"))The value can be retrieved via:
(op:foo u) ----> "echo" (op:union-value u) ---->"echo" (op:union-discriminator u) ---->3
module M {
typedef string foo;
const long r = 1 + 3;
};
From the above IDL, we get:
(typep "hello" 'M:foo) ---->T (typep 3 'M:foo) ---->nil M:r ---->4
The fundamental abstraction used is that of a "type" with some kind of "named members". Insofar as possible, in each case such a type maps to a Lisp type of the same name, with a keyword initarg corresponding to each named member, and readers and writers for each named member. Each reader is in the op: package; the writer is formed via (setf reader). The constructor is simply the name of the type.