10.23.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.2.3 ... 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.