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

查看:150
本文介绍了将prolog引擎嵌入到DLL中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在使用最近嵌入prolog推理引擎的C ++应用程序,如标题所述,我现在正在尝试生成一个DLL而不是一个可执行文件,因此我可以在另一个项目中使用它。既然我刚刚开发DLL,我以为我可以从一个小例子开始。我有3个文件:




  • 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/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天全站免登陆