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" long c_sum_array(long cnt, int32 *mem) { int i; long 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.0.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 long c_sum_array( long, int32 *);