2

I'm building a C++ library (windows, DLL) and I'd like to embed swi-prolog for some functionalities.
What I'm doing is:

#include <Windows.h>
#include <SWI-Prolog.h>

BOOL WINAPI DllMain(
    HINSTANCE hinstDLL,  // DLL モジュールのハンドル
    DWORD fdwReason,     // 関数を呼び出す理由
    LPVOID lpvReserved   // 予約済み
)
{
    BOOL result = TRUE;

    switch(fdwReason)
    {
        case DLL_PROCESS_ATTACH:
        {
            char* av[]{"libswipl.dll"};

            _putenv(R"(SWI_HOME_DIR=C:\Program Files (x86)\swipl\)");

            if(!PL_initialise(1, av))
            {
                result = TRUE;
            }
            else
            {
                PL_halt(1);
                result = FALSE;
            }

            break;
        }

        case DLL_PROCESS_DETACH:
        {
            result = PL_cleanup(1);
            break;
        }
        case DLL_THREAD_ATTACH:
        case DLL_THREAD_DETACH:
            break;
    }

    return result;
}

and including "libswipl.lib", renamed from "swipl\lib\libswipl.dll.a".

First it gives errors because of missing dll, so I copied those in my executable folder until it was happy (specifically, libswipl.dll;libgmp-10.dll;pthreadGC2.dll).

I don't need to include a pl file into the executable (is this what swipl-ld does?) because I would like to add facts and rules dinamically by code later, so it's ok to initialize with a clear state.

What I'd like to know is, how do I get rid of the dependencies (SWI_HOME_DIR) and make it stand-alone?

キキジキ
  • 1,443
  • 1
  • 25
  • 44
  • 1
    ??? ...including "libswipl.lib", renamed from "swipl\lib\libswipl.dll.a". ??? – CapelliC Dec 09 '12 at 11:29
  • well, the documentation says to include the lib file associated to the dll, but I couldn't find any. My lib contents (fresh install) are "jpl.jar", "libpthreadGC2.dll.a", "libswipl.dll.a" and "plterm.dll.a". Even searching, the whole swipl folder does not contain a single lib file. – キキジキ Dec 09 '12 at 11:39
  • You can [create a lib from a dll](http://www.coderetard.com/2009/01/21/generate-a-lib-from-a-dll-with-visual-studio/) (or [here](http://support.microsoft.com/kb/131313)), but if you used the wrong lib file, you would get linker errors. So I think the file you renamed was the right one. – wimh Dec 09 '12 at 11:54
  • It's no clear to me what build tools you are using. Windows builds require MinGW. – CapelliC Dec 09 '12 at 11:58
  • I'm using visual studio 2012. The compiling goes fine, no problems. If I understood correctly, the documentation explains how to compile prolog into an executable, or how to compile a library that can be used from prolog. What I wanted to do is incorporate the prolog engine inside my program. – キキジキ Dec 09 '12 at 12:04
  • 1
    according to [this doc](http://www.swi-prolog.org/windows.html) there is no need to rename the dll.a to lib – CapelliC Dec 09 '12 at 12:06
  • @Wimmel thanks, I didn't know of that. Probably, as you said, it was the right one because all the "missing symbol" linking errors disappeared. – キキジキ Dec 09 '12 at 12:07
  • @CapelliC I see! I was tricked by the linux-ish extension I suppose. Anyway, do you have some suggestions about my original question? I really could use some help. – キキジキ Dec 09 '12 at 12:19
  • @キキジキ you might try to ask both questions separate. – wimh Dec 09 '12 at 18:48
  • @Wimmel I was just going to remove the secondary question myself because I kinda figured it out. – キキジキ Dec 09 '12 at 19:48

2 Answers2

1

First I would not recommend to initialize prolog in the DllMain, pls see here:

But, you could still use it and check if dependent libraries are there, not only libswipl.dll which changed to swipl.dll from the version 5.10, but also:

  • pthreadVC2.dll for 64 bits or pthreadVC.dll for 32 bits
  • plterm.dll (optional, terminal emulation)

Then, I would add and export a function to initialize prolog, and set required parameters (like: saved-state filename or boot32.prc/boot64.prc, flags e tc).

And, you dont need SWI_HOME_DIR when you pass all required parameters to your PL_initialise function.

Also, in case of MultiThreaded environment, these calls are required: PL_thread_attach_engine and PL_thread_destroy_engine.

More on the topic is here: swi-prolog

Cheers!

Community
  • 1
  • 1
Oleh Sky
  • 125
  • 1
  • 13
  • one more thing: be careful with the PL_halt(int status), as it calls exit(status)... – Oleh Sky May 24 '13 at 15:52
  • Thanks, much clearer now! Last time I tried I just passed "libswipl.dll" in the PL_initialise parameters and it was enough, does adding for example "-x boot32.prc" make a difference? By the way I have the 6.3.15 build and the library is still libswipl.dll . – キキジキ May 25 '13 at 10:54
  • see [PL_initialize](http://www.swi-prolog.org/pldoc/man?CAPI=PL_initialise) you can pass -x with you savedstate (sooner or later you need to, simple to compile your programs and initial facts), then you could pass a script (-s/-F/-f/-l) file to init your state, or goal to execute (-g). To list all of them, just run swipl.exe -h or check in Manual. – Oleh Sky May 25 '13 at 15:07
  • sorry for misleading info on DLL: the name was changed for EXE not DLL. I will edit post. – Oleh Sky May 25 '13 at 15:08
0

I have never used SWI-Prolog, but looking at the installed files, some of the files installed there seem to be required to run the prolog engine.

If you mean you want to embed everything into your dll, it would probably not be possible, the only way would be modifying swi-prolog itself. But that won't be easy.

If you just don't want to require swi-prolog to be installed to have your program running. you can create your own installer which included all files to run swi-prolog, and include it in your own (sub)directory. You still need to set SWI_HOME_DIR, but you will know the relative directory to your executable.

If you don't want to use _putenv to set SWI_HOME_DIR, you can also set SWI_HOME_DIR in the windows system settings to the correct value.

wimh
  • 15,072
  • 6
  • 47
  • 98
  • 1
    Oh, that's it! When you instance the prolog engine you need to pass the executable path (in this case, you have to compile using swipl-ld.exe to embed a prolog file inside the resulting executable) or the home folder. In the latter case, it uses the boot file to create the initial empty state. So by including the the required dll files, the boot, and eventually the files regarding additional libraries referenced, it should be enough. – キキジキ Dec 11 '12 at 08:21