如何在 C 函数内返回由 CLIPS 处理的值或对象?

问题描述 投票:0回答:1

如何从 C 函数返回 CLIPS 中的值或对象?

嗨。我正在尝试将 CLIPS 与 C 函数结合起来,然后我将从 Swift 调用它们。我的想法是将命令作为参数传递给 C 函数,在这些 C 函数内使用 CLIPS 执行操作,然后将这些 C 函数的结果返回到 Swift。我的第一个方法是这样的(提前为我缺乏 CLIPS 知识以及 C 语言知识而道歉):

char * test_clips(char *command) {
    CLIPSValue cv;
    Environment *env;
    StringBuilder *sb;
    char *out = NULL;
    
    env = CreateEnvironment();
    sb = CreateStringBuilder(env, 1024);
    
    // The file hello.clp must be in the same directory
    // as the CLIPS executable or you must specify the
    // full directory path as part of the file name.
    
    //Load(env, "hello.clp");
    //Reset(env);
    //Run(env, -1);
  
    Build(env, "(defrule hello => (println \"Hello World!\"))");
    //Build(env, "(+ 3 4)");
    Eval(env, "(reset)", &cv);
    Eval(env, "(run)", &cv);
    
    SBAppend(sb, cv.lexemeValue->contents);
    if (cv.header->type == SYMBOL_TYPE) {
        SBAppend(sb, cv.lexemeValue->contents);
    } else {
        SBAppend(sb, "No hay saludo!...");
    }
    out = SBCopy(sb);
    
    SBDispose(sb);
    DestroyEnvironment(env);
    
    return out;
}

但是当我执行这段代码时它没有返回消息,我做错了什么?问候。

我正在尝试使用传递自己的命令的内部 CLIPS 语句从 Swift 调用 C 函数,并且这些函数返回由 CLIPS 处理的结果。

c clips
1个回答
0
投票

当您调用 Eval 时,您指定的命令/函数的返回值存储在您提供的 CLIPSValue 参数中。在您的代码中,最后一个 Eval 调用执行 (run) 命令并将值存储在变量 cv 中。 (run) 命令没有返回值,因此变量 cv 中存储的内容没有任何意义。我确信有一些编程语言是例外,但通常打印是打印函数的副作用;打印的内容不用作函数的返回值。因此,CLIPS 中没有设置任何内容来获取规则中 println 语句的输出并将其用作运行命令的返回值。

我添加了一些示例代码,显示了从 CLIPS 传输数据的两种不同机制。一种是添加用户定义的函数,您可以使用该函数从规则的操作中调用。另一个展示了如何通过将信息存储在事实中来传回信息。

main.c:

#include "clips.h"

int main(
  int argc,
  char *argv[])
  {
   Environment *env;
   CLIPSValue cv, sv;
   
   env = CreateEnvironment();

   Build(env,"(deftemplate message (slot value))");
   Build(env,"(defrule hello => (myfun \"User Function Callout\"))");
   Build(env,"(defrule goodbye => (assert (message (value \"Fact Slot Retrieval\"))))");
   
   Eval(env,"(reset)",NULL);
   Eval(env,"(run)",NULL);
   
   Eval(env,"(find-all-facts ((?f message)) TRUE)",&cv);
   
   if (cv.header->type == MULTIFIELD_TYPE)
     {
      for (size_t i = 0; i < cv.multifieldValue->length; i++)
        {
         if (cv.multifieldValue->contents[i].header->type == FACT_ADDRESS_TYPE)
           {
            Fact *theFact = cv.multifieldValue->contents[i].factValue;
            FactSlotValue(env,theFact,"value",&sv);
            if (sv.header->type == STRING_TYPE)
              { printf("%s\n",sv.lexemeValue->contents); }
           }
        }
     }

   DestroyEnvironment(env);

   return -1;
  }

用户函数.c:

#include "clips.h"

void UserFunctions(Environment *);
void MyFunFunction(Environment *,UDFContext *,UDFValue *);
  
void UserFunctions(
  Environment *env)
  {
   AddUDF(env,"myfun","v",1,1,"s",MyFunFunction,"MyFunFunction",NULL);
  }

void MyFunFunction(
  Environment *theEnv,
  UDFContext *context,
  UDFValue *returnValue)
  {
   UDFValue theArg;
   const char *theString;

   if (! UDFFirstArgument(context,STRING_BIT,&theArg))
     { return; }

   theString = theArg.lexemeValue->contents;
   
   printf("%s\n",theString);
  }

输出:

User Function Callout
Fact Slot Retrieval
© www.soinside.com 2019 - 2024. All rights reserved.