All Manuals > Foreign Language Interface User Guide and Reference Manual > 3 FLI Pointers

3.5 More examples of allocation and pointer allocation

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.

3.5.1 Allocating an integer

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>

3.5.2 Allocating a pointer to a pointer to a void

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