将prolog引擎嵌入到DLL中 [英] Embedding prolog engine in a dll
问题描述
-
likes.pl
:定义谓词的示例prolog文件喜欢/ 2 -
likes.cpp
:定义函数get_food()
调用PlQuery
并将结果返回到std :: string
-
food.cpp
:使用DLL列出山姆喜欢的各种食物
所以我的第一个尝试是如下:
swipl-ld -shared -dll -o喜欢-goal true likes.cpp likes.pl -DLIKES_EXPORTS -v
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初始化和保存状态。
我尝试过在<$ c $中调用PlEngine c> get_food()和 food.cpp
main()
函数,相同的结果。所以现在我坚持第一个选择,因为我更有兴趣在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喜欢.pl -DLIKES_EXPORTS -v
g ++ -o food.exe food.cpp -Lc:/程序文件(x86)/ swipl / lib-lswipl -Ic:/程序文件(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屋!