⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 clipsmfc_old.cpp

📁 clips专家系统内核打包类,很有参考性.
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/*
clipsMFC.cpp : implementation file for a CLIPS Wrapper class using MFC

Notes:			Allows encapsulation of the 'C' interface for CLIPS. Also adds
				enhanced parameter/error checking, and simplifies the
				housekeeping that is needed in the main application as a lot of
				this is handled by class instance variables. It should also be
				relatively easy to expand this class to cover more of the
				CLIPS interface than I initially used.
			**  there are a lot of definitions in the first portion of the 
			    header file, please review these settings and adjust to suit the
				needs of YOUR project.

Author(s):	Mark Tomlinson, Michael Giordano
			

Version:		2.0

Revision	WHO		Date  		WHY
--------------------------------------------------
1.1			mdt		5/4/96		instance & dynaload
1.5         mdt     6/19/97		Added Build()
1.6			mdt	    9/29/97		added createfact
1.7			mjg		1/21/98		added ODBC Query
1.8         mjg     1/29/98		added UserDefined router support
1.9         mdt     1/31/98		minor bug fixes, mods to UserDefined routers   
2.0			mdt/mjg 2/21/98		minor bug in WriteFactSlot, added UserFunctions
2.2			mdt		7/15/98		Major overhaul of route buffers
2.3         sj      5/12/99     AddResetFunction()
3.0			mdt		5/16/99		First major overhaul in many moons
								fixed many little problems and
								cleaned up code (such as using CLIPS
								pointer validation routines), all
								references to external CString* converted
								to CString &  and added the following:
								PeriodicCleanup()

*/
#ifndef _DEBUG
#pragma optimize("",off)
#pragma optimize("q",off)
#endif

#define NON_VERBOSE_LOG 1
#define DEF_CB_PRIORITY 1


//stream i/o
#include <iostream.h> 	//ios
#include <fstream.h> 	//ofstream                  
#include <direct.h>

#ifndef __AFX_H__
	#include <afx.h>
#endif
#ifndef __AFXCOLL_H__
	#include <afxcoll.h>
#endif

#define __defc
//default loop count
int		Defcount;
//running flag
bool	Running;
//error log file
char	ErrorLog[_MAX_PATH] = "";

//macro used to check GPA() return values
#define CHKFNPTR(p,s)	if (p == NULL) { \
	                    char t_buf[100]; \
						sprintf(t_buf,"Unable to locate CLIPS entry point for function: %s",s); \
						::MessageBox(NULL,t_buf,"CLIPSWrap::GetProcAddress",MB_OK); \
						return FALSE; }
//macro to load a given proc address from CLIPS DLL
#define GPA(p,t,n)	p = (t) GetProcAddress(m_hLib,n); \
				    CHKFNPTR(p,n)
/////////////////////////////////////////////////////////////////////////////
// exported functions for DLL suppport/callbacks


//include for all clips defs
extern "C"	{
#include <dynclips.h>
}
//class definition
#include <clipsmfc.h>
#ifdef USE_ODBC
	//Header files for ODBC Query
	#include <afxdb.h>
	#include "rsvarcol.h"	//Class definition for CVarRecordset
#endif

extern "C"	{
/*	some global variables */
//array of pointer to the string buffers for memory routes
//CObjArray
CStringArray*	pRoutes[NUMROUTES];
CString*	    pRteNames[NUMROUTES];
//string arrays to manage lists of file routes
CStringArray*	FileRoutes;
CStringArray*	FileNames;
}

//prototype for generic CB function which can be set to fire periodically
void far       (*CBfunctPtr)(bool);

/*
This function handles out of memory conditions for CLIPS, this is a callback
from CLIPS.
*/ 
extern "C" int DllExport ReportMemoryProblems(unsigned long p)
{
//!!!    (dl_PeriodicCleanup)(TRUE, TRUE);
	return 0;
}

/*
This function captures which routes we will handle, this is a callback
from CLIPS.
*/
extern "C" int DllExport captureQuery(char *router)
{
	/*
	If the router comes from stdout, stdin, wclips, wdisplay, ...,
  then we will accept the output.  Otherwise, pass the buck onto
  someone else. This could be done using a string container class.
	*/
	//return true if we handle this route, and false if not.
	if(IsDefaultRouter(router))	{
		return TRUE;
	}
	return (GetRouteNum(0,router) != -1);
}

/*
This function actually handles what to do with the routed
information. This is a callback from CLIPS.
*/
extern "C" int DllExport capturePrint(char far* router, char far* str)
{
 static CString message;
	CString		hold;
	CString		Route;
	int			rnum = 0, i, n = -1;

    if(strlen(ErrorLog) == 0)	{
		//get Windows directory - this is where we want to put it
		memset(ErrorLog,0,256);
		GetWindowsDirectory(ErrorLog,255);
		strcat(ErrorLog,"\\CLIPSDLL.ERR");
	}

	// Dump all routes to the file CLIPSDLL.ERR
	// if not handled in another way, in this code
	// the "other way" is to copy the string into
	// an array which was initialized elsewhere.
	// since CLIPS does not actually format the route
	// data you could add a routine to collect all the
	// output data on a given route until a CRLF was recieved
	// thus building a single string of output.
	//(ex-) (str-cat ?item1 ?item2 ?item3 ... "some text" ...)
	//      (printout wwhatever ..........)
	bool fHandled = false;

	hold = str;
	// loop in case there is more than 1 buffer/route
	while ((rnum = GetRouteNum(rnum,router)) != -1)	{
		if(pRoutes[rnum] != NULL)	{
			pRoutes[rnum]->Add(str);
			fHandled = true;
		}
		++rnum;
	}
	Route = router;
	if (FileRoutes!=NULL)	{
		for(i = 0; i < FileRoutes->GetSize(); i++)	{
			if(FileRoutes->GetAt(i) == Route)	{
				n = i;
			}
			if(n != -1)	{
				ofstream *ofFile;
				ofFile = new ofstream(FileNames->GetAt(i),ios::out | ios::app | ios::binary);
				long		i = 0;

				(*ofFile) << hold;
#if VERBOSE_LOG
				(*ofFile) << "\r\n";
#endif
				fHandled = true;
				delete ofFile;
		  	}
		}
	}

	if(!fHandled)	{
		// create the error log for unhandled routes
		ofstream *ofError;
				
		ofError = new ofstream(ErrorLog,ios::out | ios::app | ios::binary);

        //is it a EOL situation?
		if((strncmp((LPCSTR)hold,"\r\n",2)!= 0)	&&
		   (strncmp((LPCSTR)hold,"\r",1)!= 0) 	&&
		   (strncmp((LPCSTR)hold,"\n",1)!= 0))	{
            if(message.GetLength() > MBUFSIZE) {  //don't let it get too big
    			(*ofError) << message;
#if VERBOSE_LOG
	    		(*ofError) << "\r\n";
#endif
                message.Empty();
            }
            if(message.GetLength() == 0)   {
    			message += "\r\n";
	    		message += "Msg from ";
    			message += (char *)router;
                message += ": ";
            }
            message += hold;
        }
        else    {
			(*ofError) << message;
#if VERBOSE_LOG
			(*ofError) << "\r\n";
#endif
            message.Empty();
		}
		delete ofError;
	}
	return TRUE;
}	//end of extern 'c' declaration block

//return ordinal number of specified route
int GetRouteNum(int start, const char far* route)
{
	int rnum = -1;

	for(int i = start; i < NUMROUTES; i++)	{
		if(pRteNames[i] != NULL)	{
			if(pRteNames[i]->CompareNoCase(route) == 0)	{
				rnum = i;
				break;
			}
		}
	}
	return rnum;
}

//check to see if router is a system defualt router name
bool IsDefaultRouter(const char * route)
{
	if((_stricmp(route, "stdout")==0)		||
	   (_stricmp(route, "werror")==0)		||
	   (_stricmp(route, "wclips")==0)		||
	   (_stricmp(route, "wdisplay")==0)	||
	   (_stricmp(route, "wdialog")==0)	||
	   (_stricmp(route, "wtrace")==0)		||
	   (_stricmp(route, "wagenda")==0)	||
	   (_stricmp(route, "wwarning")==0))	{
		return true;
	}
	return false;
}

/////////////////////////////////////////////////////////////////////////////
// CCLIPSWrap - all class implementation functions

//constructor
//note: construction does NOT load the DLL
CCLIPSWrap::CCLIPSWrap(int count)
	: factPtr (NULL), rulePtr (NULL), modulePtr (NULL), globalPtr (NULL),
	  instancePtr (NULL), classPtr (NULL), m_hLib (NULL)
{
	int i;

	Defcount = count;
	Running = false;
	m_fClipsInit = false;
	CLEARMBUF
	for(i = 0; i < NUMROUTES; i++)	{
		pRoutes[i]   = NULL;
		pRteNames[i] = NULL;
		}
	FileRoutes	  = NULL;
	FileNames	  = NULL;       
	CBfunctPtr    = NULL;
	factPtr       = NULL;
	modulePtr     = NULL;
	rulePtr       = NULL;
	globalPtr     = NULL;
	instancePtr   = NULL;
	classPtr      = NULL;
	activationPtr = NULL;
	agendaPtr     = NULL;
	templatePtr   = NULL;
	insSlotPtr    = NULL;
	tempSlotPtr   = NULL;
	fastLoad      = NULL;
	fastSave      = NULL;
}

//destructor
//cleanup memory
CCLIPSWrap::~CCLIPSWrap(void)
{
	CBfunctPtr    = NULL;
	factPtr       = NULL;
	modulePtr     = NULL;
	rulePtr       = NULL;
	globalPtr     = NULL;
	instancePtr   = NULL;
	classPtr      = NULL;
	activationPtr = NULL;
	agendaPtr     = NULL;
	templatePtr   = NULL;
	insSlotPtr    = NULL;
	tempSlotPtr   = NULL;
	fastLoad      = NULL;
	fastSave      = NULL;
	if(FileRoutes != NULL)	{
		delete FileRoutes;
		FileRoutes = NULL;
		}
	if(FileNames != NULL)	{
		delete FileNames;
		FileNames = NULL;
		}
//the route buffers in memory will not be deleted
//since we did not allocate them in this class
	for(int i = 0; i < NUMROUTES; i++)	{
		if(pRteNames[i] != NULL)	{
			delete pRteNames[i];
			pRteNames[i] = NULL;
		}
	}
}

/////////////////////////////////////////////////////////////////////////////
// virtual functions

/***************************************************************************
		Function	:	CCLIPSWrap::SetErrorLog(CString& filename)
		Author		:	Mark Tomlinson
		Desc.		:	set filename & path for error route log filename
		Returns		:	none
****************************************************************************/
void CCLIPSWrap::SetErrorLog(CString& filename)
{
	strcpy(ErrorLog,(LPCSTR)(filename));
}

/***************************************************************************
		Function	:	CCLIPSWrap::SetMsgLoopCBfn(void far (*func_ptr)(void))
		Author		:	Mark Tomlinson
		Desc.		:	set callback function which be invoked during msgpump loops
		Returns		:	none
****************************************************************************/
void CCLIPSWrap::SetMsgLoopCBfn(void far (*func_ptr)(bool))
{
	CBfunctPtr = func_ptr;
}

/****************************************************************************
		Function	: 	CCLIPSWrap::CLIPSInit(void)
		Author		: 	Mark Tomlinson
		Desc.		: 	Accessor function to CLIPS InitilizeCLIPS(), also will
						load the DLL into memory, get procedure entry points &
						initialize the default capture router.
		Returns 	: 	true on success, false if it fails.
****************************************************************************/
bool CCLIPSWrap::CLIPSInit(void)
{
	if(m_fClipsInit)
		return true;
//now decide which DLL to load...
	if(m_hLib == NULL)	{
#ifdef WIN32
		m_hLib = LoadLibrary ("clips.dll");
#else
		m_hLib = LoadLibrary ("clipsdll.dll");
#endif
	}
	if(m_hLib == NULL)
		return false;

	if(LoadDllReferences() == false)	{
		//unload the library
		FreeLibrary(m_hLib);
		m_hLib = NULL;
		return false;
	}

	//call init clips
	(dl_InitializeCLIPS)();

	//set message pump callback function to prevent a hang
	//of the system when CLIPS is doing lengthy processing
	//not exactly needed in WIN32 - essential in WIN16
#ifndef WIN32
	(dl_AddPeriodicFunction)("msgpump",MsgLoopProc,1);
#endif
	//set out of memory handler function
	(dl_SetOutOfMemoryFunction)((unsigned long)ReportMemoryProblems);

	//tell CLIPS to be quiet while loading files
	(dl_SetPrintWhileLoading)(false);

	// add router to handle output from DLL functions, (if any), although
	// you are best to assume some output so as not to overwrite the
	// windows desktop with TTY output from the DLL. Then return.
	if((dl_AddRouter)("capture", 20, (int (*)(char *))captureQuery, (int (*)(char *,char *))capturePrint, NULL, NULL, NULL))	{
		m_fClipsInit = true;
		return true;
		}
	//failed
	return false;
}

/***************************************************************************
		Function	:	CCLIPSWrap::CLIPSReset(void)
		Author		:	Mark Tomlinson
		Desc.		:	Accessor function for CLIPS Reset
		Returns		:	true on success, false on error
****************************************************************************/
bool CCLIPSWrap::CLIPSReset(void)
{
	INITCHK(false)
	(dl_Reset)();
	return true;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -