【问题标题】:Calling SWI-Prolog via C based on a DLL基于 DLL 通过 C 调用 SWI-Prolog
【发布时间】:2015-01-05 16:12:04
【问题描述】:

我再次需要帮助。我尝试基于 Windows 上的 dll 通过 C 调用 SWI-Prolog。

在我的 C 程序中,我想使用函数“consult_cooco”。 C代码看起来像

#include "consult_cooco.h"
#include <SWI-Prolog.h>

int consult_cooco( char** strInput )
{
    char *program = "consult_cooco";
    char *plav[2];
    int rval;

    char* xmlstring;
    term_t av;
    predicate_t p;

    /* make the argument vector for Prolog */
    plav[0] = program;
    plav[1] = NULL;

    putenv("SWI_HOME_DIR=C:\\Program Files (x86)\\swipl");
    if ( !PL_initialise(1, plav ) )
        PL_halt(1);


    av = PL_new_term_refs(2);
    p = PL_predicate("start_dialog", 2, "user");

    printf("consult_cooco:: input >> %s\n",*strInput);

    // Prolog call: start_dialog('ohne Zitrone, mit Joghurt, Butter',XML).
    av = PL_new_term_refs(2);
    PL_put_atom_chars(av, *strInput);

    if ( PL_call_predicate(NULL, PL_Q_NORMAL, p, av) )
    { 
        rval = PL_get_atom_chars(av+1, &xmlstring);
        printf(" >> xmlstring of %s is \n\n%s (returned %i)\n",*strInput,xmlstring,rval);
    } 
    else
    {
        printf(" >> no answer found\n");
    }


    PL_halt(1);

    return 0;
}

我通过

创建了 dll
swipl-ld -shared -dll -o consult_cooco -goal true consult_cooco.c dialog.pl -DLIKES_EXPORTS -v

我通过链接 C 源代码

gcc CooCoServer.o -static-libgcc -lws2_32 -L. -lconsult_cooco -I. -o startcoocoserver

我的 Prolog 文件 dialog.pl 的开头看起来像

start_dialog( InputString, XMLResult ) :-
    create_individual_filename('dialog_','.debug',Filename),
    tell(Filename),
    process_input( InputString, WordList ),
    do(WordList, XMLResult ),
    told.

没有

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

我收到了错误

[FATAL ERROR: Could not find system resources]

如 SWI Prolog 手册中所述。

但是还是找不到Prolog谓词,错误描述是

ERROR: '$c_call_prolog'/0: Undefined procedure: start_dialog/2

start_dialog 在 dialog.pl 中定义,见上文。

我的假设是plav[0] = "consult_cooco"; 是错误的,并且没有找到指向 Prolog 文件的链接。

使用从 C 主文件开始的 exe 文件时

int consult_cooco( char** strInput )
{
    char *program = "consult_cooco";

int main( int argc, char** argv )
{
    char *program = argv[0];

它有效。它也适用于

int main( int argc, char** argv )
{
    char *program = "call_cooco";

使用 dll 时我有什么问题? char *program里面必须写什么?

非常感谢您的帮助。

【问题讨论】:

    标签: c dll ffi swi-prolog


    【解决方案1】:

    对不起,答案已经给出here

    我必须设置

    plav[0] = (char*)"startcoocoserver.exe";
    plav[1] = (char*)"-x";
    plav[2] = (char*)"dialog.exe";
    

    然后使用

    if(!PL_initialise(3, plav))
    

    需要额外的构建步骤

    swipl --goal=true --stand_alone=true -o dialog -c dialog.pl
    

    在执行其他步骤之前。然后它工作:)

    PS:我没有找到如何删除问题 - 管理员,请执行...

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-27
      • 1970-01-01
      • 2019-08-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多