In-out
parameters are always of type pointer in COM and are handled as a mixture of
in
and
out
. In particular, they have both a positional parameter and a keyword parameter, which can be used to control the value passed and conversion of the value returned respectively. Each
in-out
parameter generates a return value, which will be
eq
to the value of the keyword argument if it was passed and otherwise depends on the type of the parameter as below.
nil
then a null pointer is passed to the COM call. The positional argument should be
nil
is these cases. If the keyword argument not passed, a foreign object with dynamic extent is created to contain the value, initialized with data from the positional argument before calling the method and possibly converted back to a Lisp value on return.
string
attribute, the positional argument is handled as for the
in
argument
string
case and the keyword argument is handled as for the
out
argument
string
case. The functions co-task-mem-alloc and co-task-mem-free should be used to manage the memory for the string itself.
size_is
attribute, the positional argument is handled as for the
in
argument array case and the keyword argument is handled as for the
out
argument array case. To update an existing array, pass it as both the positional and keyword argument values.
nil
.
fli:dereference
.import "unknwn.idl";
[ object,
uuid(E37A70A0-EFC9-11D5-BF02-000347024BE1)
]
interface IArgumentExamples : IUnknown
{
typedef [string] char *argString;
HRESULT inoutMethod([in, out] int *inoutInt,
[in, out] argString *inoutString,
[in] int inoutArraySize,
[in, out, size_is(inoutArraySize)]
int *inoutArray);
}
the method
inout-method
can receive and return Lisp objects like this:
(let ((in-array #(7 6)))
(multiple-value-bind (hres int string array)
(call-com-interface (arg-example i-argument-examples
inout-method)
42
"the answer"
(length in-array)
in-array)
;; int is of type integer
;; string is of type string
;; array is of type array
))
or fill an existing array like this:
(let* ((in-array #(7 6))
(out-array (make-array (length in-array))))
(multiple-value-bind (hres int string array)
(call-com-interface (arg-example i-argument-examples
inout-method)
42
"the answer"
(length in-array)
in-array
:inout-array out-array)
;; int is of type integer
;; string is of type string
;; array is eq to out-array, which was filled
))
or update an existing array like this:
(let* ((inout-array #(7 6)))
(multiple-value-bind (hres int string array)
(call-com-interface (arg-example i-argument-examples
inout-method)
42
"the answer"
(length inout-array)
inout-array
:inout-array inout-array)
;; int is of type integer
;; string is of type string
;; array is eq to inout-array, which was updated
))