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.3.1 ...
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 *);