Last week I upgraded to the latest version (4.4.1) of Sicstus Prolog for Windows. Since the Prolog engine can be embedded (royalty free) in other applications, it is useful to understand how to create a DLL (on Windows) for this purpose. In today’s article, I would like to outline this process in sufficient detail because I found the official documentation a little wanting in this area.
One important point to remember: Unlike a program written in other languages such as Lisp, Go, C++, etc., we cannot directly convert a Sicstus Prolog program into a DLL. Instead, we have to write an intermediate layer (preferably in C/C++) that loads a compiled Prolog program image into memory and invokes the desired predicates.
The example I am going to use for this article is based on the Train.pl example discussed in the Sicstus.pdf file (page 328) available as part of the product distribution.
Instead of distributing the Prolog source program, it is common practice to generate an image file (.sav) from the program and load that image at runtime. Creating the image file is straightforward.
Creating the DLL
We need a C/C++ program for the DLL. I am going to use the file Train.c explained in the example. However, the example shows the steps for building a standalone .exe file, so I will modify it slightly for building a DLL. The main change is to decorate the entry point with the __declspec(dllexport) declaration, so that it can be called from another library. This function sets up the Prolog engine, loads the saved program image and calls the prolog predicate connected to generate solutions.
In order to build a DLL from this code, we need Visual Studio 2017 (64 bit) compiler. I have that installed already on my machine.
Next, we need the Developer Command Prompt for VS2017. See this article to learn how to launch it.
By default, this environment is configured for generating x86 code. Since we need to build for 64 bit target, we have to run the vcvars64.bat file. On my machine, the file is located in G:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\VC\Auxiliary\Build directory. Once this batch file is run, the environment is correctly set up for 64 bit target. You can check this by running the CL command at the prompt. See image below.
Lets us now CD to the directory where the sourse code is present. I have included Sicstus Prolog Bin directory in my System PATH, so that I can conveniently run the utilities without explicitly using the full path (of course, if you want, you can update the PATH variable each time the command prompt appears).
Next, we have to run the Sicstus utility spld to generate the DLL from our source. It took me a few attempts to find out that I have to also include cmdproc.obj and intrpt.obj files to build the DLL correctly (I was getting a linker error otherwise). I created a batch file build-dll.bat to run spld with correct arguments. It is recommended to use –verbose option so that we can see the various steps in the process. I am including the transcript of the build process along with other files.
Once the process is complete, we will have the following files in the current (project) directory:
– train.dll
– train.exp
– train.lib
– train.pdb
This completes the DLL creation step.
Using the DLL
Let us create a C++ program to consume the DLL just created. Here is a simple program that does this:
As you can see, the above program dynamically loads the DLL and calls designated the entry point. Although it is possible to use the VS2017 IDE to create a project for this purpose, I chose the simpler commandline alternative. Here is the command:
> cl cppexample.cpp “G:/SICStusProlog-4.4.1-VC15/bin/sprt4-4-1.lib” /Fe: cppexample.exe
Notice that we have to include the Sicstus runtime library. The generated executable file is cppexample.exe.
Running the Program
Before running the program we have to ensure that the DLL we created is accessible at runtime. I copied it to the current directory where the executable is located. The other file that we need in the current directory is the saved image file train.sav. Sicstus Prolog runtime DLL sprt4-4-1.dll is assumed to be in the PATH.
Here is the output from the program:
Nice! The program displays the paths from Stockholm to Orebro as expected. And the Result Code is zero, as it should be.
I hope the procedure for building and using a Sicstus Prolog DLL is clear from this article. All the relevant files used in this example are available here.
Have a nice weekend!
Recent Comments