CLIPS与MFC之间的交互方法总结
更多文章参见个人网站
最近,碰到很多同学询问MFC如何与CLIPS进行交互,简单地说就是,如何把CLIPS里的推导结果显示在MFC的程序中(或者是文本框)。相信目前使用MFC的做CLIPS交互的同学还有很多,毕竟大学还是主要教授这些,那么有这样不会交互问题的同学还有很多,很多人可是在CLIPS的IDE中得到结论,甚至可以输出到Terminal(不会的看前面的文章),但却不能将结论输出到MFC的程序中。
今天我就在这里说几种方法,算是抛砖引玉,太LOW轻砸。
方法一、中转。
第一个方法就是LOW到不行的低级方法啦,不过可以解燃眉之急,对那些基本没有编程经验和工程经验,甚至是非计算机专业的同学还是可以借鉴一下的。简单说下流程:CLIPS推理–>输出结果到本地–>读取本地信息–>显示到MFC。废话不过说了,直接上干货!
- 在CLIPS的知识库文件中将结论输出到本地。需要在RHS内添加以下代码:
(open "out.txt" example "w");;以只写的方式打开名为“out.txt”的文件,没有则创建
(printout example "False" crlf);;输出结论
(close example)
- 在MFC内读取本地信息。
这样,推导结论通过本地TXT文本的中转,可以显示在MFC程序内。
方法二、CLIPS路由映射函数
原理就是通过将CLIPS内的print函数路由到用户自定义的函数,从而可以直接在知识内将结论直接print到MFC的文本框。直接上干货!
void *theEnv;
theEnv = __CreateEnvironment();
__EnvAddRouterWithContext(theEnv,"output",255, MyQueryFunction, MyPrintFunction);
__EnvBuild(theEnv, "(defrule hello" " =>" " (printout t \"Hello World.\"crlf)" );
__EnvReset(theEnv);
__EnvRun(theEnv, -1);
__DestroyEnvironment(theEnv);
}
int MyQueryFunction(void* env, const char* logicalname)
{
if (strcmp(logicalname, "output") == 0)
{ return 1;
}
return 0;
}
int MyPrintFunction(void* env,const char* logicalname,const char* buffer)
{
// TODO: write out the info in buffer
CEdit* pBoxOne;
pBoxOne = (CEdit*)GetDlgItem(AfxGetMainWnd()->m_hWnd,IDC_EDIT1);
pBoxOne->SetWindowText((LPCTSTR)buffer);
}
方法三、内存读取
内存读取的意思就是在CLIPS做完推理后,直接从他的Environment内读取推理的结果,也就是它的运行内存。读取内存需要用到CLIPS自身的一些函数,详情请参照《CLIPS高级指南》在这里我们使用GetFactSlot函数。MFC内添加如下代码:
m_editSummand=__EnvEval(theEnv, "(MAIN::get-list)", DOToPointer(result1));
for (int i = 0; i < m_editSummand; i++)
{
__EnvGetFactSlot(theEnv, DOToPointer(result1), "name", DOToPointer(result2));
}
其中,result1和result2均为 DATA_OBJECT 。通过以上操作已将结果存储到了result2内。CLIPS知识库内添加以下部分:
(deffunction get-list()
(bind ?facts (find-all-facts ((?f boy))
( >= ?f:age 1 ))))