我正在编写一个应在某个时候获取defglobal变量的值并对其进行更改的应用。为此,我执行以下操作:
DATA_OBJECT cur_time_q;
if (!EnvGetDefglobalValue(CLIEnvironment, cur_timeq_kw, &cur_time_q)) return CUR_TIME_GLBVAR_MISSING;
uint64_t cur_time = t_left;
SetType(cur_time_q, INTEGER);
void* val = EnvAddLong(CLIEnvironment, cur_time);
SetValue(cur_time_q, val);
EnvSetDefglobalValue(CLIEnvironment, cur_timeq_kw, &cur_time_q);
我从“高级编程指南”中部分采用了这种方法,并且效果很好,但是我有一些问题:
EnvAddLong(...)
是否添加一个值,该值将保留在内存中,直到环境被破坏?如果具有此代码片段的函数需要进行数千次迭代,则可能会占用内存并增加其他API函数(例如EnvRun(...)
)的执行时间吗?EnvEval("(bind ...)")
之类的东西吗?CLIPS高级编程指南中提供了有关CLIPS如何处理垃圾收集的信息。诸如EnvAddLong之类的API调用(用于创建要传递给其他API函数的值)不会触发垃圾回收。通常,导致代码执行或取消分配数据结构(如运行,重置,清除和评估)的API调用会触发垃圾回收,并将取消分配由EnvAddLong之类的函数创建的任何瞬时数据。因此,如果您的程序设计反复将值分配给全局变量然后运行,那么一旦确认数据为垃圾数据并且不再被任何CLIPS数据结构引用,您分配的任何CLIPS数据结构最终都会被释放。
如果您可以轻松地构造一个字符串以传递给Eval函数,则通常比执行多个API调用来获得相同的结果要容易得多。
API已在6.4版中进行了全面修订,因此许多任务(例如,为defglobal赋值)可以仅一步完成,而无需执行多个步骤。
CLIPSValue rv;
Defglobal *global;
mainEnv = CreateEnvironment();
Build(mainEnv,"(defglobal ?*x* = 3.1)");
Eval(mainEnv,"?*x*",&rv);
printf("%lf\n",rv.floatValue->contents);
global = FindDefglobal(mainEnv,"x");
if (global != NULL)
{
DefglobalSetInteger(global,343433);
Eval(mainEnv,"(println ?*x*)",NULL);
DefglobalGetValue(global,&rv);
printf("%lf\n",rv.floatValue->contents);
}