问题
I've been working on a C++ application that embeds a prolog reasoning engine lately and, as stated in the title, I am now trying to generate a DLL instead of an executable so I can use it in another project. Since I am new to DLL development, I thought I could start with a small example. I have 3 files:
likes.pl
: sample prolog file defining the predicate likes/2likes.cpp
: defining the functionget_food()
that callsPlQuery
and return the results in astd::string
food.cpp
: using the DLL to list all kinds of food that Sam likes
So my first try was the following:
swipl-ld -shared -dll -o likes -goal true likes.cpp likes.pl -DLIKES_EXPORTS -v
g++ -o food.exe -s food.cpp -L. -llikes -I. -L"c:/program files (x86)/swipl/lib" -lswipl -I"c:/program files (x86)/swipl/include"
First of all, let me point out that when get_food()
only returns a string without any call to prolog, this works fine. However, after two days of investigation, I can't figure out how to get the DLL to call prolog. I think there are two things I am possibly doing wrong, maybe both: the PlEngine intialization and the saved state.
I've tried both calling PlEngine in get_food()
and in food.cpp
main()
function, same result. So for now I am sticking to the first option since I am more interested in having everything done in the DLL. I see here (Embedding SWI-Prolog in a dll) that it can later be done in the DllMain
but also that it is not recommended. What is the best way to do it? Should I give food.exe asargv[0]
or something else (libswipl.dll? a saved state?)
Secondly, I noticed that one difference when using swipl-ld to generate a DLL instead of an EXE is that it ommits the lines:
swipl.exe -f none -F none -g true -t"consult(['likes.pl']),qsave_program('pltmp-4228.exe',[goal=true,toplevel=prolog,init_file=none])"
cat pltmp-4228.exe >> food.exe
So I tried to do it manually, replacing the random name by "mystate.exe" and using the Win32 copy /b
command to append it to food.exe. This makes food.exe a toplevel console where I can test likes/2
. Is it because the Dll doesn't have any main()
? Anyway, this is the furthest I could get for now and I guess there were a few things to change in the qsave_program/2
second argument. I tried replacing toplevel=prolog
with stand_alone=true
. By the way, the command example given at the end of (http://www.swi-prolog.org/pldoc/doc_for?object=section%282,%272.10%27,swi%28%27/doc/Manual/compilation.html%27%29%29) doesn't generate any file at all. Anyway, I can't figure out if and how exactly I have to do this either.
Can anyone tell me how to solve this?
回答1:
Forgive me, as this is not really a precise answer to your problem, just a report about my experience on the topic.
I've been working on pqConsole, a DLL that introduces Qt bindings via the C++ interface.
pqConsole, while still in development, has so far found its way in swipl-win, and I had the joy to work together with Jan Wielemaker making this little big step for Prolog audience widening.
I would suggest to build your DLL with G++, to get binary compatibility, and release SWI-Prolog component(s) as-is.
If you like Qt, you can use QtCreator for interface design, see for instance fdqueens. There you can also see how I used to embed .pl in Qt project resources, to have more control about the application (users can't mess with the Prolog logic that's required from other parts) and over the release (no .pl to add, just the executable/DLL).
HTH
回答2:
Solved it! In case somebody needs the answer someday:
int main(int argc, char *argv[]) {
char* av[50];
av[0] = (char*)"food.exe";
av[1] = (char*)"-x";
av[2] = (char*)"mystate.exe";
if(!PL_initialise(3, av))
cout << "NO init\n" ;
else
cout << "OK init\n" ;
cout << get_food() ;
getchar();
return 0;
}
Then:
swipl --goal=true --stand_alone=true -o mystate -c likes.pl
swipl-ld -shared -dll -o likes -goal true likes.cpp likes.pl -DLIKES_EXPORTS -v
g++ -o food.exe food.cpp -L"c:/program files (x86)/swipl/lib" -lswipl -I"c:/program files (x86)/swipl/include" -L. -llikes -I.
来源:https://stackoverflow.com/questions/18636501/embedding-prolog-engine-in-a-dll