Passing Pointers

Pointers should be passed through the foreign interface using the specification

     address(typename)
     
They could also be passed as integers, but there are two added advantages for using the address specification. The first is that a stand-alone tool could check for consistency between the foreign declarations and the foreign code. The second advantage is for possible optimizations on platforms whose pointers require more than 29 bits.

The typename is there so that a stand-alone tool could know what kind of argument to pass or what kind of result to demand and typename should be the name used in the foreign language to identify the type of object named by the pointer. It is sufficiently important to be able to check the foreign/3 declarations that Prolog will issue a warning if the typename is not an atom, but it makes no other use of the typename. The typename can even be omitted entirely, using address as an argument specification.

is the argument type desired.]

Note that programs should not rely on numeric relations between foreign language pointers being true of the Prolog integers to which they are converted.

See fli-p2f-fex-poi for an example of passing pointers through the foreign interface. For further examples, see library(charsio) and library(vectors).

     Prolog:  +address(typename)
     C:       typename *x
     Pascal:  type ptr = ^typename;
              x: ptr
     FORTRAN: typename x(*)
     

The argument must be instantiated to an integer, otherwise the call fails. If the argument is 0, the foreign function will receive the NULL pointer. Otherwise the argument will be converted to a pointer. The coding is system-dependent. All you can rely on is that NULL and "malloc() pointers" can be passed from the foreign language to Prolog and that Prolog can then pass the same pointers back to the foreign language.

FORTRAN programmers will note that +address(integer) and +address(float) parameters are useful for passing arrays to FORTRAN, but since FORTRAN has no pointer data type (and no equivalent of malloc(3)), address results are not possible. Therefore arrays cannot be constructed in FORTRAN and then passed to Prolog; they must be constructed in C or Pascal. fli-p2f-fex-poi gives an example where arrays are constructed in C and later passed to a FORTRAN routine.

The typename must be an atom, but is otherwise ignored by Prolog. It is present for the benefit of stand-alone tools, which could check

that your Prolog foreign/3 facts are compatible with your C source files.

     Prolog:  -address(typename)
     C:       typename **x;
              *x = ...
     Pascal:  type ptr = ^typename;
              var x: ptr;
              x = ...
     FORTRAN: Not supported
     

A pointer to a pointer is passed to the foreign function. It is assumed that the function will overwrite this variable with the result it wishes to return. This result should be either the NULL pointer or a malloc() pointer. When the function returns, the result is converted to a Prolog integer, which is then unified with the corresponding argument of the Prolog call. The argument can be of any type; if it cannot be unified with the returned integer, the call fails. If the foreign function does not set the result, the result is undefined.

The typename must be an atom, but is otherwise ignored by Prolog. It is present for the benefit of stand-alone tools, which could check

that your Prolog foreign/3 facts are compatible with your C source files.

     Prolog:  [-address(typename)]
     C:       typename *f(...)
                {
                   typename *x;
                   return x;
                }
     Pascal:  type ptr = ^typename;
              function f(...): ptr;
                var x: ptr;
                begin
                  f := x;
                end
     FORTRAN: Not supported
     

No argument is passed to the foreign function. The return value from the foreign function is assumed to be a pointer to an object of the type indicated by typename. This pointer should be either NULL or a malloc() pointer. It is converted to a Prolog integer, which is then unified with the corresponding argument of the Prolog call. The argument can be of any type; if it cannot be unified with the returned integer, the call fails.

The typename must be an atom, but is otherwise ignored by Prolog. It is present for the benefit of stand-alone tools, which could check

that your Prolog foreign/3 facts are compatible with your C source files.

     Prolog:  +address
     C:       char *x
     Pascal:  type charp = ^char;
              x: charp
     FORTRAN: Not supported
     

This is equivalent to +address(char) (see +address(typename) above). Note that +address(char) is not useful in FORTRAN because FORTRAN will not accept a pointer to a character array as representing that array. Therefore +address is not allowed in FORTRAN. To pass a character array to FORTRAN use the +string(N) argument type as described in fli-p2f-atm-spf.

     Prolog:  -address
     C:       char **x
              *x = ...
     Pascal:  type charp = ^char;
              var x: charp;
              x = ...
     FORTRAN: Not supported
     

This is equivalent to -address(char) (see -address(typename) above).

     Prolog:  [-address]
     C:       char *f(...)
                {
                  char *x;
                  return x;
                }
     Pascal:  type charp = ^char;
              function f(...): charp;
                var x: charp;
                begin
                  f := x;
                end
     FORTRAN: Not supported
     

This is equivalent to [-address(char)] (see [-address(typename)] above).