3

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

  • likes.pl: 定义谓词 likes/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()我已经尝试在函数中和函数中调用 PlEngine food.cpp main(),结果相同。所以现在我坚持第一个选项,因为我对在 DLL 中完成所有事情更感兴趣。我在这里看到(在 dll 中嵌入 SWI-Prolog),以后可以在 dll 中完成,DllMain但也不推荐这样做。最好的方法是什么?我应该给 food.exeargv[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”并使用 Win32copy /b命令将其附加到 food.exe。这使 food.exe 成为我可以测试的顶级控制台likes/2。是因为Dll没有main()吗?无论如何,这是我目前能得到的最远距离,我想qsave_program/2第二个论点有一些地方需要改变。我尝试toplevel=prologstand_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)根本不生成任何文件。无论如何,我也不知道我是否必须以及如何准确地做到这一点。

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

4

2 回答 2

0

请原谅我,因为这并不是对您问题的准确答案,只是关于我在该主题上的经验的报告。

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

pqConsole 虽然仍在开发中,但到目前为止已经在swipl-win中找到了自己的方式,我很高兴与 Jan Wielemaker 合作,为 Prolog 扩大受众群体迈出了一大步。

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

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

高温高压

于 2013-09-05T14:51:19.437 回答
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.
于 2013-09-09T07:11:34.863 回答