Did you know ... Search Documentation:
Pack ffi -- doc/cmem.md

Accessing C data

Interaction with native C functions requires the ability to work with C data structures from Prolog. Arithmetic types (various sizes of integers and floating point numbers) are simple as such parameters are easily converted from Prolog numbers and the return value is easily converted back. Arithmetic types have no interesting internal structure and need no memory management such as malloc() and free().

Arrays and structures however do have internal structure and typically do need memory management. Managing such data is achieved in two layers. The high level layer reasons in terms of abstract types, while the low level layer deals with pointers and access to primitive C (scalar) data types.

Pointers

The core of the memory access functions is formed by a SWI-Prolog blob of type c_ptr. Such a blob wraps a C pointer. It has the following properties:

  • The type is an atom or a term struct(Name), union(Name) or enum(Name) that represents the C type of an element.
  • The size is an integer representing the size of an element in bytes.
  • The count represents the number of elements. It is -1 if this is not know.
  • An indirection level. If 0 (zero), it is a pointer to an (array of) object(s) of the indicated type. If 1 it is a pointer to a pointer of objects of the indicated type, etc.
  • An optionally associated free function is called if the blob is garbage collected by the atom garbage collector.

Pointer blobs are created using predicates c_alloc/2, c_cast/3 and c_load/2 if the addressed object is not a scalar type. Pointer blobs are also created by C functions if the return value is a pointer or an argument is declared as an output argument returning a pointer. A pointer allocated with c_alloc/2 owns the pointer, reclaiming the associated memory as the blob is garbage collected. Function return and output pointers may be declared to own the pointe using the ~(Type,Free) type declaration. See c_import/3.

Pointer blobs are subject to (atom) garbage collection. Atom reference counts are used to avoid collecting of pointers that depend on other pointers. Notable c_load/2 references the original pointer if it returns a pointer inside the area of the original pointer and c_store/2 references the Value if the Value is a pointer.

Types

A type is either a primitive type or a constructed type.

Basic types

The following basic types are identified:

Signed integers
char, schar, short, int, long and longlong
Unsigned integers
uchar, ushort, uint, ulong and ulonglong
Floats
float and double
Pointers
*(Type), closure (pointer to a function)

In addition, the type wchar_t is recognised by the library to facilitate portable exchange of Unicode text represented as wide character strings.

Note that we have char, schar and uchar. The latter two are explicitly signed or unsigned. Whether char is signed or not depends on the C compiler used to compile the this package.

Constructed types

The constructed types are struct(Name), union(Name) and enum(Name). The c_import/3 directive extracts types that are (transitively) reachable from imported functions to the current module. In addition, types can be defined using c_struct/1 and c_union/1. Such declarations can be used to create and access C binary data without using library functions.

Sorry, No manual entry for c_struct/2

Sorry, No manual entry for c_union/2

The defined types may be examined using the following interface:

Sorry, No manual entry for c_current_enum/3

Sorry, No manual entry for c_current_struct/1

Sorry, No manual entry for c_current_struct/3

Sorry, No manual entry for c_current_struct_field/4

Sorry, No manual entry for c_current_union/1

Sorry, No manual entry for c_current_union/3

Sorry, No manual entry for c_current_union_field/3

Sorry, No manual entry for c_current_typedef/2

Sorry, No manual entry for c_expand_type/2

Sorry, No manual entry for c_type_size_align/3

The high level interface

Sorry, No manual entry for c_alloc/2

Sorry, No manual entry for c_cast/3

Sorry, No manual entry for c_load/2

Sorry, No manual entry for c_store/2

Sorry, No manual entry for c_nil/1

Sorry, No manual entry for c_is_nil/1

The low level interface

The low-level interface is build around a SWI-Prolog blob that represents a C pointer with some metadata. A blob is similar to a Prolog atom, but blobs are typed and they are intended to deal with binary data.

Sorry, No manual entry for c_calloc/4

Sorry, No manual entry for c_free/1

Sorry, No manual entry for c_disown/1

Sorry, No manual entry for c_alloc_string/3

Sorry, No manual entry for c_load/4

Sorry, No manual entry for c_load_string/4

Sorry, No manual entry for c_load_string/5

Sorry, No manual entry for c_store/4

Sorry, No manual entry for c_offset/6

Sorry, No manual entry for c_typeof/2

Sorry, No manual entry for c_sizeof/2

Sorry, No manual entry for c_alignof/2

Sorry, No manual entry for c_address/2

Sorry, No manual entry for c_dim/3