foreign/[2,3] hook

Synopsis

:- discontiguous foreign/2, foreign/3.

foreign(*Routine, *ForeignSpec)

foreign(*Routine, *Language, *ForeignSpec)

Describes the interface between Prolog and the foreign Routine. The user has to define a foreign/3 or the fact for every foreign function that is to be called from Prolog. Used by load_foreign_files/2 and load_foreign_executable/2.

Arguments


Routine atom
An atom that names a foreign code Routine
Language atom
An atom that names the Language in which Routine is written. It must be one of c, pascal or fortran.
ForeignSpec foreign_spec
A term of the form PredName(Argspec, Argspec, ...) where:

PredName
the name of the Prolog predicate
Argspec
an argument specification (for each argument of the predicate) One of the following:
                +integer    +float    +single   +double
                -integer    -float    -single   -double
               [-integer]  [-float]  [-single] [-double]
               
                 +atom      +term     +string
                 -atom      -term     -string
                [-atom]    [-term]   [-string]
               
                +string(N)    +address(T)
                -string(N)    -address(T)
               [-string(N)]  [-address(T)]
               

where N is a positive integer and T is a foreign type name.

Description

foreign/2 is a special case of foreign/3 where Language is C. foreign/2 is for backward compatibility.

The user has to define a foreign/3 fact for every foreign function that is to be called from Prolog. Note that Routine does not have to be the same as PredicateName. Arguments are passed to the foreign function as specified in ForeignSpecs


+type
specifies that an argument is to be passed to the foreign function.
-type
specifies that an argument is to be received from the foreign function.
[-type]
argument is used to obtain the return value of a foreign function call. At most one "return value" argument can be specified.

For more details about the passing arguments through the foreign interface, see fli-ffp-ppc-api.

The foreign/3 facts are used only in the context of a load_foreign_files/2 command and can be removed once the foreign files are loaded.

If you have foreign/3 facts in different files, Prolog will warn you that foreign/3 has been previously defined in another file. This is generally not a problem if you are using the module system.

load_foreign_files/2 will only look for foreign/3 facts defined in its source module.

Exceptions

Errors in the specification of foreign/3 will only be detected at load_foreign_files/2 time. Otherwise defining a foreign/3 fact is just like defining any other Prolog fact.

Tips

A good practice in loading several foreign files is to insert the call to load_foreign_files/2 into the file that defines foreign/3 as an embedded command. For example,

             foreign(f11, c, f11(+integer)).
             foreign(f12, c, f12(+atom, -atom)).
             foreign_file('f1', [f11, f12]).
             :- load_foreign_files('f1', []),
                abolish([foreign/3,foreign_file/2]).
     

Examples

solve() is a C function that takes three integer coeffecients of a quadratic equation and returns the two solutions. We assume that the solutions are not imaginary numbers.

                                       
a.pl
foreign(solve, c, solve(+integer, +integer, +integer, -double, -double)). foreign_file('a', [solve]). :- load_foreign_files(['a'], ['-lm']), abolish([foreign/3, foreign_file/2]).
                                        
a.c
void solve(a, b, c, f1, f2) long int a, b, c; double *f1; double *f2; { *f1 = (-b + sqrt(b*b - 4*a*c)) / 2 * a; *f2 = (-b - sqrt(b*b - 4*a*c)) / 2 * a; }

See Also

load_foreign_files/2, foreign_file/2, extern/1 fli-p2f