В последнее время я работал над приложением C ++, которое включает механизм рассуждений пролога, и, как указано в заголовке, теперь я пытаюсь сгенерировать DLL вместо исполняемого файла, чтобы я мог использовать его в другом проекте. Поскольку я новичок в разработке DLL, я подумал, что могу начать с небольшого примера. У меня 3 файла:
likes.pl
: пример файла пролога, определяющего предикат лайков / 2likes.cpp
: определение функцииget_food()
, которая вызываетPlQuery
и возвращает результаты вstd::string
food.cpp
: использование DLL для вывода списка всех видов еды, которые нравятся Сэму
Итак, моя первая попытка была следующей:
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()
возвращает только строку без какого-либо вызова пролога, это работает нормально. Однако после двух дней расследования я не могу понять, как заставить DLL вызывать пролог. Я думаю, что есть две вещи, которые я делаю неправильно, может быть, обе: инициализацию PlEngine и сохраненное состояние.
Я пробовал вызывать PlEngine как в get_food()
, так и в food.cpp
main()
, результат тот же. Так что пока я придерживаюсь первого варианта, поскольку меня больше интересует, чтобы все выполнялось в DLL. Я вижу здесь (встраивание SWI-Prolog в 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
. Я пробовал заменить toplevel=prolog
на stand_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) вообще не создает никаких файлов. Во всяком случае, я тоже не могу понять, нужно ли мне это делать и как именно.
Кто-нибудь может сказать мне, как это решить?