【问题标题】:Embedding prolog engine in a dll在 dll 中嵌入 prolog 引擎
【发布时间】:2013-09-09 07:09:23
【问题描述】:

我最近一直在开发一个嵌入 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()food.cpp main() 函数中调用 PlEngine,结果相同。所以现在我坚持第一个选项,因为我对在 DLL 中完成所有事情更感兴趣。我看到这里 (Embedding SWI-Prolog in a dll) 以后可以在 DllMain 中完成,但也不建议这样做。最好的方法是什么?我应该给 food.exe asargv[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 第二个参数有一些需要改变的地方。我尝试用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) 末尾给出的命令示例根本不会生成任何文件。无论如何,我也无法弄清楚我是否必须以及如何做到这一点。

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

【问题讨论】:

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


    【解决方案1】:

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

    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.
    

    【讨论】:

      【解决方案2】:

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

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

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

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

      如果你喜欢 Qt,你可以使用 QtCreator 进行界面设计,例如fdqueens。 在那里你还可以看到我过去是如何将 .pl 嵌入到 Qt 项目 resources 中的,以便对应用程序进行更多控制(用户不能弄乱必需的 Prolog 逻辑来自其他部分)和发布版本(无需添加 .pl,只需添加可执行文件/DLL)。

      HTH

      【讨论】:

      • > 我建议使用 G++ 构建您的 DLL,以获得二进制兼容性,并按原样发布 SWI-Prolog 组件。对不起,但我不明白你在这里的确切意思。我的 DLL 中是否只有一些 C++ 代码?那么我的程序如何能够使用我的序言代码中定义的所有谓词?我需要的是一种让 API 调用某些逻辑的方法。我确信有一种方法可以在 swi-prolog 中正确且轻松地完成它(一旦你知道要使用什么参数)......
      猜你喜欢
      • 2023-03-21
      • 2012-03-07
      • 1970-01-01
      • 2020-10-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-16
      • 2014-02-08
      相关资源
      最近更新 更多