Did you know ... Search Documentation:
Pack ffi -- README.md

Dynamic calling C from Prolog

This package deals with calling C functions from shared objects (DLLs) from Prolog without writing wrappers. There are several libraries that allows for creating an argument vector for a C function dynamically and call the function. One such library is libffi.

Giving such a library, calling C functions with arithmetic types (integers, floats) is easy, but we still have to deal with structs, unions, enums and the fact that most C libraries do not define the target type directly but use some typedef that binds the concrete type depending on the platform. This package parses the C header file (`.h`) or even a concrete C source file to extract the actual function return and parameter types and all type definition that are involved in these types. In addition it allows fetching constants defined using `#define` macros.

Below is an example making the POSIX statfs() function available.

:- use_module(library(ffi)).
:- use_module(library(cerror)).

:- c_import("#include <sys/vfs.h>",
            [ libc ],
            [ statfs(string, -struct(statfs), [int])
            ]).

statfs(File, FsStat) :-
    statfs(File, FsStat, Status),
    posix_status(Status, statfs, file, File).

The returned pointer may be handed to c_load/2 to extract fields. For example, to get the number of available blocks on the current file system we can make the call below. Note that we did not make any declarations about the structure or the involved integer types.

?- statfs(".", FsStat), c_load(FsStat[f_bavail], A).
FsStat = <C struct statfs[1]>(0x55a2c9d5bae0),
A = 66197957.

Installation

  • Make sure libffi is installed. This is available as package on various systems.
  • Clone this repo
  • Make a link from the `.../swipl/pack/ffi` to the cloned directory
  • Run in Prolog: ?- pack_rebuild(ffi).

Windows installation

Documentation

There is not yet public documentation. With all proper tools installed (Prolog, LaTeX) and a Linux machine you should be able to type make in the doc directory to build the (incomplete) documentation.

Here is a PDF version, created at Feb 18, 2018

Status

  • Portability
    • Tested on Linux (Fedora 26 and Ubuntu 17.10), MacOSX and Windows using MinGW. Mainly limited by libffi.
  • Functionality
    • All major foreseen features are implemented.
    • It is likely that high-level conversions such as between a Prolog list and C array will be added. Such conversions are easily written in Prolog though.
  • API Stability
    • Overall the API is not likely to change much. Possibly the * as prefix operator will be changed to postfix. One may wish to write *(Type) to avoid ambiguity.
  • Documentation
    • First incomplete draft. Please also see the directories test and examples for concrete code examples. Notably examples/python provides a rudimentary Python interface.
  • Testing
    • Only basic functionality is tested. Many more combinatins of types and different ways to define them need to be tested.