Out
parameters are always of type pointer in COM and never appear as positional arguments in the Lisp call. Instead, there is a keyword argument named after the parameter, which can be used to pass an object to be modified by the method. In addition, each
out
parameter generates a return value, which will be
eq
to the value of keyword argument if it was passed and otherwise depends on the type of the parameter as described below.
nil
then a null pointer is passed to the method.
string
attribute is converted to a Lisp string if the keyword is not passed. If the keyword is passed, the memory for the string might need to be freed by co-task-mem-free if nothing else does this.
size_is
attribute will be converted to a Lisp array if the keyword is not passed and the element type is not a foreign aggregate type. If the keyword argument is not passed then a new Lisp array is made. If the value of the keyword argument is a Lisp array then that is filled.
struct
, the keyword argument must be passed and its value must be as a foreign pointer. This pointer is passed directly to the method.
iid_is
attribute, a com-interface pointer is returned using the indicated iid parameter to control the interface name.
fli:dereference
.import "unknwn.idl";
[ object,
uuid(E37A70A0-EFC9-11D5-BF02-000347024BE1)
]
interface IArgumentExamples : IUnknown
{
typedef [string] char *argString;
HRESULT outMethod([out] int *outInt,
[out] argString *outString,
[in] int outArraySize,
[out, size_is(outArraySize)] int *outArray);
}
the method
out-method
can return Lisp objects like this:
(multiple-value-bind (hres int string array)
(call-com-interface (arg-example i-argument-examples
out-method)
8)
;; int is of type integer
;; string is of type string
;; array is of type array
)
or fill an existing array like this:
(let ((out-array (make-array 5)))
(multiple-value-bind (hres int string array)
(call-com-interface (arg-example i-argument-examples
out-method)
(length out-array)
:out-array out-array)
;; int is of type integer
;; string is of type string
;; array is eq to out-array and was filled
))
or set the contents of foreign memory like this:
(fli:with-dynamic-foreign-objects ((out-int :int)
(out-string WIN32:LPSTR))
(let* ((out-farray-size 5)
(out-farray (fli:allocate-dynamic-foreign-object
:type :int
:nelems out-farray-size)))
(multiple-value-bind (hres int string array)
(call-com-interface (arg-example i-argument-examples
out-method)
out-farray-size
:out-int out-int
:out-string out-string
:out-array out-farray)
;; Each foreign pointer contains the method's results
;; int is the foreign pointer out-int
;; string is the foreign pointer out-string
;; array is the foreign pointer out-array
;; Note that the string must be freed as follows:
(co-task-mem-free (fli:dereference out-string)))))