在dll中嵌入prolog引擎

时间:2013-09-05 12:35:15

标签: c++ dll prolog mingw swi-prolog

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

  • likes.pl:定义谓词的样本prolog文件like / 2
  • likes.cpp:定义调用get_food()并在PlQuery
  • 中返回结果的函数std::string
  • food.cpp:使用DLL列出Sam喜欢的各种食物

所以我的第一次尝试是:

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"

首先,我要指出,当get_food()只返回一个字符串而没有调用prolog时,这很好。但是,经过两天的调查,我无法弄清楚如何让DLL调用prolog。我认为我可能做错了两件事,可能是两件事:PlEngine初始化和保存状态。

我已尝试在get_food()food.cpp main()函数中调用PlEngine,结果相同。所以现在我坚持第一个选项,因为我更感兴趣的是在DLL中完成所有操作。我在这里(Embedding SWI-Prolog in a dll)看到它可以在DllMain中完成,但也不建议这样做。最好的方法是什么?我应该将food.exe作为argv[0]或其他东西(libswipl.dll?保存状态?)

其次,我注意到使用swipl-ld生成DLL而不是EXE时的一个区别是它省略了这些行:

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

所以我尝试手动执行,用“mystate.exe”替换随机名称,并使用Win32 copy /b命令将其附加到food.exe。这使food.exe成为一个顶级控制台,我可以在其中测试likes/2。是因为Dll没有main()吗?无论如何,这是我现在能得到的最远的,我想在qsave_program/2第二个论点中有一些事情需要改变。我尝试将toplevel=prolog替换为stand_alone=true。顺便说一句,(http://www.swi-prolog.org/pldoc/doc_for?object=section%282,%272.10%27,swi%28%27/doc/Manual/compilation.html%27%29%29)结束时给出的命令示例根本不生成任何文件。无论如何,我无法弄清楚我是否以及如何做到这一点。

谁能告诉我如何解决这个问题?

2 个答案:

答案 0 :(得分:0)

原谅我,因为这不是你问题的准确答案,只是关于我对这个主题的经验的报道。

我一直在研究pqConsole,这是一个通过C ++接口引入Qt绑定的DLL。

pqConsole虽然仍处于开发阶段,但到目前为止已经在swipl-win中找到了方向,我很高兴与Jan Wielemaker合作,为Prolog观众扩大了这个小步骤。

我建议用G ++构建你的DLL,以获得二进制兼容性,并按原样发布SWI-Prolog组件。

如果您喜欢Qt,可以使用QtCreator进行界面设计,例如参见fdqueens。 在那里你还可以看到我曾经在Qt项目资源中嵌入.pl,以便更好地控制应用程序(用户不会弄乱所需的Prolog逻辑从其他部分)和发布(没有.pl添加,只是可执行文件/ DLL)。

HTH

答案 1 :(得分:0)

解决了!如果有人有一天需要答案:

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;
}

然后:

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.