Embedding prolog engine in a dll

对着背影说爱祢 提交于 2020-01-14 13:57:29

问题


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/2
  • likes.cpp: defining the function get_food() that calls PlQuery and return the results in a std::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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!