将prolog引擎嵌入dll [英] Embedding prolog engine in a dll

查看:243
本文介绍了将prolog引擎嵌入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 
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/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?

解决方案

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆