Я строю библиотеку C ++ (Windows, DLL), и я хотел бы встроить SWI-пролог для некоторых функций.
Что я делаю, это:
#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) и сделать их автономными?
Я никогда не использовал SWI-Prolog, но, глядя на установленные файлы, кажется, что некоторые из установленных там файлов необходимы для запуска механизма пролога.
Если вы имеете в виду, что хотите внедрить все в вашу dll, это, вероятно, было бы невозможно, единственным способом было бы модифицировать сам swi-prolog. Но это будет нелегко.
Если вы просто не хотите требовать установки swi-prolog для запуска вашей программы. Вы можете создать свой собственный установщик, включающий все файлы для запуска swi-prolog, и включить его в свой (под) каталог. Вам все еще нужно установить SWI_HOME_DIR, но вы будете знать относительный каталог вашего исполняемого файла.
Если вы не хотите использовать _putenv для установки SWI_HOME_DIR, вы также можете установить SWI_HOME_DIR в настройках системы Windows на правильное значение.
Во-первых, я бы не рекомендовал инициализировать пролог в DllMain, Пожалуйста, смотрите здесь:
Но вы все равно можете использовать его и проверить наличие зависимых библиотек, а не только libswipl.dll который изменился на swipl.dll с версии 5.10, но также:
Затем я добавил бы и экспортировал функцию для инициализации пролога и установил необходимые параметры (например, имя файла сохраненного состояния или boot32.prc / boot64.prc, flags e tc).
И вам не нужно SWI_HOME_DIR когда вы передаете все необходимые параметры вашей функции PL_initialise.
Также, в случае многопоточной среды, эти вызовы необходимы: PL_thread_attach_engine а также PL_thread_destroy_engine.
Больше по теме здесь: SWI-Prolog
Ура!