All Manuals > Foreign Language Interface User Guide and Reference Manual > 7 Function, Macro and Variable Reference

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)

Arguments
body
Forms to be executed with bindings in effect.
var
A symbol to be bound to a pointer to a foreign object.
foreign-type
A foreign type descriptor.
initial-element
The initial value of the newly allocated objects.
initial-contents
A list of values to initialize the contents of the newly allocated objects.
fill
An integer between 0 to 255.
nelems
An integer specifying how many copies of the object should be allocated. The default value is 1.
size-slot
A symbol naming a slot in the object.
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 evaluaed the forms in body as an implicit progn. Each element of bindings is a list which caused var to be bound to a pointer to a locally allocated instance of 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 above, which is supported in LispWorks 5.1 and later.

Examples

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;
};

Non-Windows 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 1.4 An example of dynamic memory allocation.

See also

5.2.4 Modifying a string in a C function
allocate-dynamic-foreign-object
free-foreign-object
with-coerced-pointer


Foreign Language Interface User Guide and Reference Manual - 01 Dec 2021 19:34:58