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.
To allocate an integer in C:
(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)
you could simply do:
(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.
Foreign Language Interface User Guide and Reference Manual - 01 Dec 2021 19:34:57