• Places
    • Home
    • Graphs
    • Prefixes
  • Admin
    • Users
    • Settings
    • Plugins
    • Statistics
  • CPACK
    • Home
    • List packs
    • Submit pack
  • Repository
    • Load local file
    • Load from HTTP
    • Load from library
    • Remove triples
    • Clear repository
  • Query
    • YASGUI SPARQL Editor
    • Simple Form
    • SWISH Prolog shell
  • Help
    • Documentation
    • Tutorial
    • Roadmap
    • HTTP Services
  • Login

12.4.25 Embedding SWI-Prolog in other applications
All Application Manual Name SummaryHelp

  • Documentation
    • Reference manual
      • Foreign Language Interface
        • The Foreign Include File
          • Embedding SWI-Prolog in other applications
            • PL_initialise()
            • PL_winitialise()
            • PL_is_initialised()
            • PL_set_resource_db_mem()
            • PL_toplevel()
            • PL_cleanup()
            • PL_cleanup_fork()
            • PL_halt()
            • Threading, Signals and embedded Prolog
    • Packages
Availability:C-language interface function
bool PL_set_resource_db_mem(const unsigned char *data, size_t size)
This function must be called at most once and before calling PL_initialise(). The memory area designated by data and size must contain the resource data and be in the format as produced by qsave_program/2. The memory area is accessed by PL_initialise() as well as calls to open_resource/3.237This implies that the data must remain accessible during the lifetime of the process if open_resource/3 is used. Future versions may provide a function to detach the resource database and cause open_resource/3 to raise an exception.

For example, we can include the bootstrap data into an embedded executable using the steps below. The advantage of this approach is that it is fully supported by any OS and you obtain a single file executable.

  1. Create a saved state using qsave_program/2 or
    % swipl -o state -c file.pl ...

  2. Create a C source file from the state using e.g., the Unix utility xxd(1):
    % xxd -i state > state.h

  3. Embed Prolog as in the example below. Instead of calling the toplevel you probably want to call your application code.
    #include <SWI-Prolog.h>
    #include "state.h"
    
    int
    main(int argc, char **argv)
    { if ( !PL_set_resource_db_mem(state, state_len) ||
           !PL_initialise(argc, argv) )
        PL_halt(1);
    
      return PL_toplevel();
    }

Alternative to xxd, it is possible to use inline assembler, e.g. the gcc incbin instruction. Code for gcc was provided by Roberto Bagnara on the SWI-Prolog mailinglist. Given the state in a file state, create the following assembler program:

        .globl _state
        .globl _state_end
_state:
        .incbin "state"
_state_end:

Now include this as follows:

#include <SWI-Prolog.h>

#if __linux
#define STATE _state
#define STATE_END _state_end
#else
#define STATE state
#define STATE_END state_end
#endif

extern unsigned char STATE[];
extern unsigned char STATE_END[];

int
main(int argc, char **argv)
{ if ( !PL_set_resource_db_mem(STATE, STATE_END - STATE) ||
       !PL_initialise(argc, argv) )
    PL_halt(1);
  return PL_toplevel();
}

As Jose Morales pointed at https://github.com/graphitemaster/incbin, which contains a portability layer on top of the above idea.

ClioPatria (version V3.1.1-51-ga0b30a5)