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?
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.
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!
来源:https://stackoverflow.com/questions/13785922/embedding-swi-prolog-in-a-dll