2

我正在构建一个 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 的作用吗?),因为我想稍后通过代码动态地添加事实和规则,因此可以使用清晰的状态进行初始化。

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

4

2 回答 2

1

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

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

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

然后,我将添加和导出一个函数来初始化 prolog,并设置所需的参数(例如:保存状态文件名或 boot32.prc/boot64.prc、标志等)。

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

此外,在多线程环境的情况下,需要这些调用:PL_thread_attach_enginePL_thread_destroy_engine

有关该主题的更多信息在这里:swi-prolog

干杯!

于 2013-05-24T15:42:33.153 回答
0

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

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

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

如果不想使用 _putenv 设置 SWI_HOME_DIR,也可以在 windows 系统设置中将 SWI_HOME_DIR 设置为正确的值。

于 2012-12-09T20:57:11.430 回答