The functions allocate-dynamic-foreign-object, allocate-foreign-object, alloca, and malloc can take the keyword arguments :type
and :pointer-type
. It is important to understand the difference between these two arguments.
The :type
argument is used to specify the name of the FLI type to allocate. Once such an object has been allocated a foreign pointer of type (:pointer
type)
is returned, which points to the allocated type. Without this pointer it would not be possible to refer to the object.
The :pointer-type
argument is used to specify a FLI pointer type. If it is used then the value pointer-type should be of the form (:pointer
type) or be defined as a FLI pointer type. The function then allocates an object of type type, and a pointer to the object of type type is returned.
(int *)malloc(sizeof(int))
You can allocate the integer from LispWorks using the :type
argument:
(fli:allocate-foreign-object :type :int)
=> #<Pointer to type :INT = #x007E1A60>
Alternatively you can allocate the integer from LispWorks using the :pointer-type
argument:
(fli:allocate-foreign-object
:pointer-type '(:pointer :int))
=> #<Pointer to type :INT = #x007E1A60>
Suppose you need to call a C function that takes a void **
argument, defined as follows:
struct arg_struct
{
int val;
};
void func_handle_init(void **h)
{
struct arg_struct *handle = NULL;
handle = (struct arg_struct *)malloc(sizeof(struct arg_struct));
memset(handle, 0, sizeof(struct arg_struct));
handle->val = 12;
*h = handle;
}
With this foreign function definition:
(fli:define-foreign-function
(func-handle-init "func_handle_init"
:source)
((handle (:pointer (:pointer :void))))
:result-type :void
:language :ansi-c)
(setq handle
(fli:allocate-foreign-object :type :pointer))
(func-handle-init handle)
but do not forget to also free the pointer:
(fli:free-foreign-object handle)
Another approach is to allocate the pointer on the stack. In this case you do not need to free it explicitly:
(fli:with-dynamic-foreign-objects ((handle :pointer))
(func-handle-init handle))
Yet another approach is to define the foreign function like this:
(fli:define-foreign-function
(func-handle-init "func_handle_init"
:source)
((:ignore (:reference-return (:pointer :void))))
:result-type :void
:language :ansi-c)
Then call the function like this:
(func-handle-init)
and it will return the handle. This works because the :reference-return type allocates the temporary void **
within the function and returns its contents.
LispWorks Foreign Language Interface User Guide and Reference Manual - 29 Sep 2017