将Prolog引擎嵌入DLL中

3
我最近在开发一个嵌入了Prolog推理引擎的C++应用程序,现在我想生成一个DLL而不是可执行文件,以便在另一个项目中使用它。由于我对DLL开发还不熟悉,所以我想从一个小例子开始。我有3个文件:
- likes.pl:定义谓词likes/2的示例Prolog文件 - 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.cppmain()函数中调用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
解决了!以防将来有人需要答案:

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.

0

非常抱歉,我的答案并不能很精确地解决你的问题,只是我在这个话题上的经验报告。

我一直在开发pqConsole,这是一个通过C++接口介绍Qt绑定的DLL库。

尽管pqConsole仍处于开发阶段,但它已经被引入了swipl-win,我很高兴能够与Jan Wielemaker一起为Prolog受众扩大迈出这一小步。

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

如果你喜欢Qt,可以使用QtCreator进行界面设计,例如fdqueens。 在那里,你还可以看到我是如何将.pl嵌入Qt项目资源中的,这样可以更好地控制应用程序(用户无法干扰其他部分所需的Prolog逻辑)和发布(无需添加.pl文件,仅有可执行文件/DLL)。

希望对你有所帮助。


我建议使用G++构建您的DLL,以获得二进制兼容性,并按原样发布SWI-Prolog组件。很抱歉,我不明白您的确切意思。我的DLL中只会有一些C++代码吗?那么我的程序如何能够使用在我的Prolog代码中定义的所有谓词?我需要一种方法来获取调用某些逻辑的API。我相信在swi-prolog中有一种正确且易于使用的方法(一旦您知道要使用哪些参数)。 - MnaerwwreanM

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接