NextPrevUpTopContentsIndex

with-dynamic-foreign-objects

Macro
Summary

Allocates memory for a list of foreign objects, executes a list of forms which may use the objects across the scope of the macro, and then deallocates the foreign objects.

Package

fli

Signature

with-dynamic-foreign-objects bindings &body body => last

bindings ::= (( var foreign-type )*)

body ::= form *

Arguments

bindings

A list of variable bindings.

var

A symbol to be bound to a foreign type.

foreign-type

A foreign type descriptor to be bound to the variable var .

body

A list of forms to be executed with bindings in effect.

form

A form to be executed.

Values

last

The value of the last form in body .

Description

The macro with-dynamic-foreign-objects binds variables according to the list bindings , and then executes body . Each element of bindings is a list which binds a symbol to a pointer which points to a locally allocated instance of a foreign type. The lifetime of the bound foreign objects, and hence the allocation of the memory they take up, is within the scope of the with-dynamic-foreign-objects function.

Any object created with allocate-dynamic-foreign-object within body will automatically be deallocated once the scope of the with-dynamic-foreign-objects function has been left.

Only standard foreign types can be bound using bindings . Foreign pointer types should be allocated using allocate-dynamic-foreign-object.

Example

This example shows the use of with-dynamic-foreign-objects with an implicitly created pointer.

Windows version:

typedef struct {
 int one;
 float two;
} foo ;
 
__declspec(dllexport) void __cdecl init_alloc(foo *ptr, int a, float b)
{
 ptr->one = a;
 ptr->two = b;
};

Unix/Linux/Macintosh version:

typedef struct  {
 int one;
 float two;
} foo ;
 
void init_alloc(foo * ptr, int a, float b)
{
 ptr->one = a;
 ptr->two = b;
};

Here are the FLI definitions interfacing to the above C code:

(fli:define-c-typedef (foo (:foreign-name "foo"))
                      (:struct (one :int) (two :float)))
 
(fli:define-foreign-function (init-alloc "init_alloc" :source)
                             ((ptr (:pointer foo))
                              (a :int) 
                              (b :float))
                             :result-type
                             :void
                             :language
                             :ansi-c
                             :calling-convention
                             :cdecl)

Try this test function which uses with-dynamic-foreign-objects to create a transient foo object and pointer:

(defun test-alloc (int-value float-value &optional (level 0))
  (fli:with-dynamic-foreign-objects ((object foo))
    (init-alloc object int-value float-value)
    (format t "~%Level - ~D~&   object : ~S~&   slot one : ~S~&   slot two : ~S~&"
            level object 
            (fli:foreign-slot-value object 'one) 
            (fli:foreign-slot-value object 'two))
    (when (> int-value 0)
      (test-alloc (1- int-value) 
                  (1- float-value) (1+ level)))
    (when (> float-value 0)
      (test-alloc (1- int-value) 
                  (1- float-value) (1+ level)))))
(test-alloc 1 2.0)
=>
Level - 0
   object : #<Pointer to type FOO = #x007E6338>
   slot one : 1
   slot two : 2.0
 
Level - 1
   object : #<Pointer to type FOO = #x007E6340>
   slot one : 0
   slot two : 1.0
 
Level - 2
   object : #<Pointer to type FOO = #x007E6348>
   slot one : -1
   slot two : 0.0
 
Level - 1
   object : #<Pointer to type FOO = #x007E6340>
   slot one : 0
   slot two : 1.0
 
Level - 2
   object : #<Pointer to type FOO = #x007E6348>
   slot one : -1
   slot two : 0.0

A further example using with-dynamic-foreign-objects and a pointer created explicitly by allocate-dynamic-foreign-object is given in An example of dynamic memory allocation.

See also

allocate-dynamic-foreign-object
free-foreign-object
with-coerced-pointer


LispWorks Foreign Language Interface User Guide and Reference Manual - 13 Sep 2005

NextPrevUpTopContentsIndex