All Manuals > LispWorks Foreign Language Interface User Guide and Reference Manual > 5 Function and Macro Reference

NextPrevUpTopContentsIndex

with-dynamic-foreign-objects

Macro
Summary

Does the equivalent of dynamic-extent for foreign objects.

Package

fli

Signature

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

bindings ::= ( binding *)

binding ::= ( var foreign-type &key initial-element initial-contents fill nelems size-slot )

body ::= form *

Arguments

var

A symbol to be bound to a foreign type.

foreign-type

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

form

A form to be executed with bindings in effect.

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.

initial-element , initial-contents , fill , nelems and size-slot initialize the allocated instance as if by allocate-foreign-object.

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.

Compatibility note

There is an alternative syntax for binding with an optional initial-element which is the only way to supply an initial element in LispWorks 5.0 and previous versions. Like this:

binding ::= ( var foreign-type &optional initial-element )

This alternative syntax is deprecated in favor of the keyword syntax for binding defined in Signature above which is supported in LispWorks 5.1 and later.

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")
    ((ptr (:pointer foo))
     (a :int) 
     (b :float))
  :result-type :void
  :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 - 7 Dec 2011

NextPrevUpTopContentsIndex