Встраивание пролога в dll

Я работал над приложением C ++, которое в последнее время встраивает механизм рассуждений пролога, и, как указано в заголовке, я сейчас пытаюсь сгенерировать DLL вместо исполняемого файла, чтобы я мог использовать ее в другом проекте. Поскольку я новичок в разработке DLL, я подумал, что могу начать с небольшого примера. У меня есть 3 файла:

  • likes.pl: пример файла пролога, определяющего предикаты лайков / 2
  • likes.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-пролога в dll) что позже это можно сделать в DllMain но и то, что это не рекомендуется. Каков наилучший способ сделать это? Должен ли я дать food.exe какargv[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) не создает никаких файлов вообще. Во всяком случае, я не могу понять, если и как именно я должен это сделать.

Может кто-нибудь сказать мне, как это решить?

2

Решение

Простите, так как это не совсем точный ответ на вашу проблему, просто отчет о моем опыте по этой теме.

Я работал над pqConsole, DLL, которая вводит привязки Qt через интерфейс C ++.

Пока pqConsole еще находится в разработке, она нашла свой путь в swipl выигрыша, и я имел удовольствие работать вместе с Яном Вилемейкером, делая этот маленький большой шаг для расширения аудитории Пролога.

Я бы предложил собрать вашу DLL с G ++, чтобы получить двоичную совместимость, и выпустить компоненты SWI-Prolog как есть.

Если вам нравится Qt, вы можете использовать QtCreator для дизайна интерфейса, см., Например, fdqueens.
Там вы также можете увидеть, как я встраивал .pl в проект Qt. Ресурсы, иметь больше контроля над приложением (пользователи не могут связываться с логикой Пролога, которая требуется из других частей) и над выпуском (без добавления .pl, только исполняемый файл / DLL).

НТН

0

Другие решения

Решил это! Если кто-то когда-нибудь нуждается в ответе:

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.
0

По вопросам рекламы [email protected]