Previous: , Up: lib-structs   [Contents][Index]


10.45.10 Example

The following example shows how to use library(structs) in a simple package for handling integer arrays. We define a module minivec with exported predicates for creating and disposing arrays, accessing its elements, and computing their sum. The summing operation is implemented in C and the rest in Prolog. Arrays are created using the array(Type) foreign type.

Note that the type declaration int32 does not have to be given in the C source code, as it appears in the automatically generated header file minivec_glue.h. Note also how the foreign type specification +pointer(int_array) corresponds to the C type declaration int32 *.

% minivec.pl
:- module(minivec, [
        new_array/2,
        get_array/3,
        put_array/3,
        dispose_array/1,
        sum_array/2
        ]).

:- load_files(library(str_decl), [when(compile_time)]).
:- use_module(library(structs)).

:- foreign_type
        int32           = integer_32,
        int_array       = array(int32).

foreign(c_sum_array, c_sum_array(+integer,
                                 +pointer(int_array),
                                 [-integer])).

foreign_resource(minivec, [c_sum_array]).

:- load_foreign_resource(minivec).

new_array(Size, array(Size,Mem)) :-
        new(int_array, Size, Mem).

get_array(Index, array(_,Mem), Value) :-
        get_contents(Mem, Index, Value).

put_array(Index, array(_,Mem), Value) :-
        put_contents(Mem, Index, Value).

dispose_array(array(_,Mem)) :-
        dispose(Mem).

sum_array(array(Size,Mem), Sum) :-
        c_sum_array(Size, Mem, Sum).
/* minivec.c */
#include "minivec_glue.h"

SP_integer c_sum_array(SP_integer cnt, int32 *mem)
{
  int i;
  SP_integer sum = 0;

  for (i=0; i<cnt; i++)
    sum += mem[i];
  return sum;
}
# session
% splfr --struct minivec.pl minivec.c
% sicstus -l minivec
% compiling /home/matsc/sicstus4/Suite/minivec.pl...
% [...]
% compiled /home/matsc/sicstus4/Suite/minivec.pl in module minivec, 30 msec 68388 bytes
SICStus 4.8.0 …
Licensed to SICS
| ?- new_array(4, A),
     put_array(0,A,1),
     put_array(1,A,10),
     put_array(2,A,100),
     put_array(3,A,1000),
     sum_array(A,S),
     dispose_array(A).
A = array(4,int_array(1264224)),
S = 1111

A fragment from the generated header file:

/* minivec_glue.h */
#include <sicstus/sicstus.h>
#include <stdlib.h>
typedef int int32;
typedef int32 *(int_array)/* really an unknown-size array */;
extern SP_integer c_sum_array( SP_integer, int32 *);

Send feedback on this subject.