我想从C++调用一个CLIPS,并将它传递给一个实例。我使用的是标准CLIPS 6.30发行版(而不是任何C++绑定)。我目前正在处理以下定义:
(defclass CFAM (is-a USER))
(deffunction drop-cfam (?cfam)
(send ?cfam delete))
(definstances KNOWN_THINGS
(cfam-1 of CFAM))我从drop-cfam调用函数C++,将要删除的实例的实例地址传递给它。
void* instancePtr = EnvFindInstance(clipsEnv,NULL,"cfam-1",false);
assert(EnvValidInstanceAddress(clipsEnv,instancePtr));
ostringstream args;
args << instancePtr;
cout << "Calling 'EnvFunctionCall for 'drop-cfam' w/ args: "<< args.str() << endl;
DATA_OBJECT callResult;
const bool callFailed = EnvFunctionCall(clipsEnv,"drop-cfam",args.str().c_str(),&callResult);
assert(!callFailed); // results in abort
const bool droppedCfam = static_cast<bool>(DOToInteger(callResult));
assert(droppedCfam);在指定的行上发生中止,而终端窗口显示:
Calling 'EnvFunctionCall for 'drop-cfam' w/ args: 0x274c290
[MSGFUN1] No applicable primary message-handlers found for delete.
[PRCCODE4] Execution halted during the actions of deffunction drop-cfam.最初,这表明我将(我相信的)实例地址传递给drop-cfam可能是不正确的。然而,终端测试表明,这不应该是问题所在:
CLIPS> (reset)
CLIPS> (instances)
[initial-object] of INITIAL-OBJECT
[cfam-1] of CFAM
For a total of 2 instances.
CLIPS> (drop-cfam (instance-address [cfam-1]))
TRUE
CLIPS> (instances)
[initial-object] of INITIAL-OBJECT
For a total of 1 instance.高级编程指南(v6.30)指出,参数应该作为字符串传递给EnvFunctionCall。该节(4.1.10)没有指定传递给EnvFunctionCall的数据类型的任何限制,也没有引用为数据类型指定词法形式的任何其他源。我不确定此时我是否能够通过EnvFunctionCall传递一个实例地址,或者我的设计是否需要修改以避免它。
编辑/变通
在我的设计中有一个问题,我假设我的系统不需要一个实例地址。可以通过将实例名称传递给EnvFunctionCall而不是地址来实现此问题的预期行为,如下所示:
EnvFunctionCall(clipsEnv,"drop-cfam","[cfam-1]",&callResult);其行为与以下行为相同:
CLIPS> (reset)
CLIPS> (drop-cfam [cfam-1])
TRUE我仍将接受任何演示如何以词法形式传递实例地址或描述终端版本为什么同时接受实例名称和实例地址的答案。
发布于 2016-08-23 02:33:29
C指针的CLIPS中没有词法表示(包括实例、事实和外部地址),因此不能直接指定它们。这既适用于解析字符串参数的API调用,也适用于终端命令和CLIPS代码。在执行过程中,地址可以从函数调用中动态绑定或返回,并且这些值可以传递给函数。这就是如何从示例函数调用中的终端中计算实例地址“(drop(实例-地址cfam-1))”。您可以使用EnvEval而不是EnvFunctionCall来计算相同类型的表达式:
EnvEval(clipsEnv,"(drop-cfam (instance-address [cfam-1]))",&callResult);https://stackoverflow.com/questions/39086210
复制相似问题