在一个DLL中嵌入SWI-Prolog

时间:2012-12-09 08:41:42

标签: c++ dll prolog swi-prolog

我正在构建一个C ++库(windows,DLL),我想为某些功能嵌入swi-prolog。
我正在做的是:

#include <Windows.h>
#include <SWI-Prolog.h>

BOOL WINAPI DllMain(
    HINSTANCE hinstDLL,  // DLL モジュールのハンドル
    DWORD fdwReason,     // 関数を呼び出す理由
    LPVOID lpvReserved   // 予約済み
)
{
    BOOL result = TRUE;

    switch(fdwReason)
    {
        case DLL_PROCESS_ATTACH:
        {
            char* av[]{"libswipl.dll"};

            _putenv(R"(SWI_HOME_DIR=C:\Program Files (x86)\swipl\)");

            if(!PL_initialise(1, av))
            {
                result = TRUE;
            }
            else
            {
                PL_halt(1);
                result = FALSE;
            }

            break;
        }

        case DLL_PROCESS_DETACH:
        {
            result = PL_cleanup(1);
            break;
        }
        case DLL_THREAD_ATTACH:
        case DLL_THREAD_DETACH:
            break;
    }

    return result;
}

包括“libswipl.lib”,从“swipl \ lib \ libswipl.dll.a”重命名。

首先它因为缺少dll而出错,所以我将它们复制到我的可执行文件夹中,直到它开心(特别是libswipl.dll; libgmp-10.dll; pthreadGC2.dll)。

我不需要在可执行文件中包含一个pl文件(这是swipl-ld的用途吗?)因为我想稍后通过代码添加事实和规则,所以可以用clear状态初始化。

我想知道的是,如何摆脱依赖关系(SWI_HOME_DIR)并使其独立?

2 个答案:

答案 0 :(得分:1)

首先我不建议在 DllMain 中初始化prolog,请参阅此处:

但是,您仍然可以使用它并检查是否存在依赖库,而不仅仅是 libswipl.dll 从版本5.10更改为 swipl.dll ,还有:

  • 64位的pthreadVC2.dll或32位的pthreadVC.dll
  • plterm.dll(可选,终端仿真)

然后,我将添加并导出一个函数来初始化prolog,并设置所需的参数(例如:saved-state filename或boot32.prc / boot64.prc,flags e tc)。

而且,当您将所有必需参数传递给PL_initialise函数时,您不需要 SWI_HOME_DIR

此外,如果是MultiThreaded环境,则需要进行以下调用: PL_thread_attach_engine PL_thread_destroy_engine

有关此主题的更多信息,请访问:swi-prolog

干杯!

答案 1 :(得分:0)

我从未使用过SWI-Prolog,但是查看installed files,安装在那里的一些文件似乎需要运行prolog引擎。

如果你的意思是想要将所有内容嵌入你的dll中,那么可能是不可能的,唯一的方法就是修改swi-prolog本身。但这并不容易。

如果您只是不想要安装swi-prolog来运行您的程序。您可以创建自己的安装程序,其中包含运行swi-prolog的所有文件,并将其包含在您自己的(子)目录中。您仍然需要设置SWI_HOME_DIR,但您将知道可执行文件的相对目录。

如果您不想使用_putenv设置SWI_HOME_DIR,您还可以将Windows系统设置中的SWI_HOME_DIR设置为正确的值。