将prolog引擎嵌入dll [英] Embedding prolog engine in a dll
问题描述
我一直在使用C ++应用程序,最近嵌入一个前言推理引擎,如标题中所述,我现在试图生成一个DLL而不是一个可执行文件,所以我可以在另一个项目中使用它。因为我是新的DLL开发,我想我可以开始一个小例子。我有3个文件:
-
likes.pl
:定义谓词/ code>:定义函数get_food()
调用PlQuery
并返回结果std :: string
-
food.cpp
:使用DLL列出山姆喜欢的各种食物
所以我的第一个尝试是以下:
swipl-ld -shared -dll -o likes -goal true likes.cpp likes.pl -DLIKES_EXPORTS -v
$ p $首先,我要指出,当
g ++ -o food.exe -s food.cpp -L。 -llikes -I。 -Lc:/程序文件(x86)/ swipl / lib-lswipl -Ic:/程序文件(x86)/ swipl / include
get_food()
只返回一个字符串而不调用任何prolog时,工作正常。然而,经过两天的调查,我不知道如何获得DLL调用prolog。我认为有两个事情,我可能做错了,也许两个:PlEngine初始化和保存的状态。
我试过调用PlEngine
get_food()
和food.cpp
。所以现在我坚持第一个选项,因为我更感兴趣的一切都在DLL中完成。我在这里看到了(将SWI-Prolog嵌入到dll 中),以后可以在
DllMain
中完成,但也不建议这样做。什么是最好的方法呢?我应该给food.exe作为argv [0]
或其他(libswipl.dll?保存的状态?)
其次,我注意到,使用swipl-ld生成DLL而不是EXE的一个区别是它省略了这些行:
swipl.exe -f none -F none -g true -tconsult(['likes.pl']),qsave_program('pltmp-4228.exe',[goal = true,toplevel = prolog,init_file = none])
cat pltmp-4228.exe>> food.exe
所以我试图手动做,用mystate.exe并使用Win32
copy / b
命令将其附加到food.exe。这使得food.exe成为一个顶级控制台,我可以测试likes / 2
。是因为Dll没有任何main()
?无论如何,这是我现在可以得到的最远,我想有一些事情要改变在qsave_program / 2
第二个参数。我试着用stand_alone = true
替换toplevel = prolog
。顺便说一句,命令示例在结束时给出( http://www.swi-prolog.org/pldoc/doc_for?object=section%282,%272.10%27,swi% 28%27 / doc / Manual / compilation.html%27%29%29 )根本不生成任何文件。无论如何,我不知道是否以及如何完成这个任务。
任何人都可以告诉我如何解决这个问题?
解决方案解决了!如果某人有一天需要答案:
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\\\
;
else
cout<< OK init\\\
;
cout<< get_food();
getchar();
return 0;
}
然后:
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 -Lc:/ program files(x86)/ swipl / lib-lswipl -Ic:/ program files(x86)/ swipl / include-L。 -llikes -I。
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?
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.
这篇关于将prolog引擎嵌入dll的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!