在软件中加入Forcal & MForcal支持
在软件中加入Forcal & MForcal支持是一件很容易的事,比直接使用Forcal设计程序要简单地多。有了MForcal提供的模块化编译功能的支持,可在软件中方便地使用脚本函数。 如果软件能动态地加载Forcal扩展库,软件将由此获得无限的可扩充性--没有人可以描述软件所能实现的全部功能,包括软件设计者自己。
本文的例子可使用VS2008 C++进行演示,编译时请将活动解决方案配置为“Release”,这个例子很容易移植到任何一个C++编译器中。这是个完整的例子,复制下来直接编译运行即可。为了减少代码,这 个例子是控制台应用程序,简单地加以改写,将它应用到实用的Windows程序中去是不难的。
该例子需要Forcal32W.dll和MForcal32W.dll的支持,若存在Forcal扩展库QuitFc32W.dll,可获得更好的演示性能:在任意可接受输入的窗口,按 Ctrl+Alt+Q(q) 键可以退出Forcal运行时的无限循环。
为了简单,该例子没有加载更多的Forcal扩展库,但实现这个功能不是很复杂。
该例子编译运行了一段简单的字符串源代码,并输出了结果。字符串源代码可以非常复杂,例如下面的代码是完全可以编译运行的:
//八皇后问题的Forcal源程序
i:(::sum,upperlim)= sum=0,upperlim=1,SetIntStackMax(1000);
i:test(row, ld, rd : pos,p : sum,upperlim)=
{
which { row != upperlim,
{ pos = and{upperlim , not[row.or(ld).or(rd)]},
while{ pos,
p = and(pos,-pos),
pos = pos -p,
test(row+p, shl(ld+p,1), shr(rd+p,1))
}
},
sum++
}
};
i:main(:n:sum,upperlim)=
{
n=15, //Queens
upperlim=shl(upperlim,n)-1,
test(0,0,0),
sum //Number of solutions
};
源代码如下:
#include <windows.h>
#include <cmath>
#include <iostream>
#include <iomanip>
#include "forcal32w.h" //Forcal头文件
using namespace std;
HINSTANCE hForcal=NULL; //动态库Forcal32W.dll的句柄;Forcal核心库,必须加载。
HINSTANCE hMForcal; //动态库MForcal32W.dll的地址;Forcal模块化编译运行库,必须加载。
HINSTANCE hQuitFc=NULL; //动态库QuitFc32W.dll的句柄;找到就加载该库。在任意可接受输入的窗口,按 Ctrl+Alt+Q(q) 键可以退出Forcal运行时的无限循环。
//动态库Forcal32W.dll的输出函数
fcInitForcal InitForcal; //初始化FORCAL
fcFreeForcal FreeForcal; //释放FORCAL动态库
fcGetRunErr GetRunErr; //获得FORCAL运行错误
fcSearchKey SearchKey; //查找一个键
fcInsertKey InsertKey; //插入一个键
//动态库MForcal32W.dll的输出函数
fcFcDll32W FD_MForcal; //MForcal的输出函数
mfcComModule ComModule; //得到编译函数的地址
mfcExeModule ExeModule; //得到计算函数的地址
mfcDeleteModule DeleteModule; //得到删除模块函数的地址
//动态库QuitFc32W.dll的输出函数
fcFcDll32W FD_QuitFc;
/////////////////////////////////////////////////
void _stdcall myDllMessage(wchar_t *ch) //输出一个字符串
{
wcout<<ch;
}
void _stdcall outl(fcIFOR ll) //输出一个整数
{
wchar_t wchNum[32];
myDllMessage(L"\r\ni: ");
_i64tow_s(ll,wchNum,32,10);
myDllMessage(wchNum);
}
void _stdcall outd(double dd) //输出一个实数
{
char chNum[32];
wchar_t wchNum[32];
int i;
myDllMessage(L"\r\n");
_gcvt_s(chNum,32,dd,16);
for(i=0;chNum[i];i++) wchNum[i]=chNum[i];
wchNum[i]='\0';
myDllMessage(wchNum);
}
void _stdcall outc(_complex cc) //输出一个复数
{
char chNum[32];
wchar_t wchNum[32];
int i;
myDllMessage(L"\r\nc: ");
_gcvt_s(chNum,32,cc.x,16);
for(i=0;chNum[i];i++) wchNum[i]=chNum[i];
wchNum[i]='\0';
myDllMessage(wchNum);
if(cc.y!=0.0)
{
if(cc.y>0.0) myDllMessage(L"+");
_gcvt_s(chNum,32,cc.y,16);
for(i=0;chNum[i];i++) wchNum[i]=chNum[i];
wchNum[i]='\0';
myDllMessage(wchNum);
myDllMessage(L"i");
}
}
/////////////////////////////////////////////////
bool myInitForcal(void) //初始化Forcal
{
hForcal=LoadLibrary(L"Forcal32W.dll");
hMForcal=LoadLibrary(L"MForcal32W.dll");
if(hForcal&&hMForcal)
{
InitForcal=(fcInitForcal) GetProcAddress(hForcal,"InitForcal");
FreeForcal=(fcFreeForcal) GetProcAddress(hForcal,"FreeForcal");
GetRunErr=(fcGetRunErr) GetProcAddress(hForcal,"GetRunErr");
SearchKey=(fcSearchKey) GetProcAddress(hForcal,"SearchKey");
InsertKey=(fcInsertKey) GetProcAddress(hForcal,"InsertKey");
InitForcal(); //Forcal32.dll初始化
FD_MForcal=(fcFcDll32W) GetProcAddress(hMForcal,"FcDll32W");
FD_MForcal(hForcal,true,0); //MForcal32.dll初始化
ComModule=(mfcComModule)SearchKey("ComModule",9,FC_PrivateKey_User);
ExeModule=(mfcExeModule)SearchKey("ExeModule",9,FC_PrivateKey_User);
DeleteModule=(mfcDeleteModule)SearchKey("DeleteModule",12,FC_PrivateKey_User);
}
else
{
if(hForcal) FreeLibrary(hForcal);
if(hMForcal) FreeLibrary(hMForcal);
MessageBox(NULL,L"找不到动态库Forcal32W.dll或MForcal32W.dll,请将这两个库放到Windows的搜索路径内!",L"Forcal & MForcal",MB_OK);
return false;
}
hQuitFc=LoadLibrary(L"QuitFc32W.dll"); //加载动态库QuitFc32W.dll
if(hQuitFc)
{
FD_QuitFc=(fcFcDll32W) GetProcAddress(hQuitFc,"FcDll32W");
FD_QuitFc(hForcal,true,0); //初始化QuitFc
}
return true;
}
void myFreeForcal(void) //释放Forcal
{
if(hQuitFc) FD_QuitFc(hForcal,false,0); //释放QuitFc
FD_MForcal(hForcal,false,0); //释放MForcal
FreeForcal(); //释放Forcal申请的空间
FreeLibrary(hForcal); //释放动态库
}
void main(void)
{
fcVOID nModule=0; //起始模块号
void *hModule; //模块句柄
fcINT ErrBegin,ErrEnd; //表达式编译出错的初始位置和结束位置
int ErrCode; //错误代码
int ErrType; //运行错误类型
wchar_t *FunName; //出错函数名
int ForType; //运行出错的表达式类型
void *ForHandle; //运行出错的表达式句柄
void *vv;
int i;
const int k=1000; //字符串源代码最大长度
wchar_t FcStr[k];
wchar_t *pForStr[]= //字符串源代码
{
L"c:(2.2+3.3i).sin().sqrt().ln(); //以c:开头是复数表达式\r\n",
L"f(x,y)=(x^2-2*x)*exp[-(x^2)-y^2-x*y]; //定义实数函数\r\n",
L"f[1.2,2.1].sin(); //计算",
L""
};
//合并字符串源代码
i=0; FcStr[0]='\0';
while(pForStr[i][0])
{
wcscat_s(FcStr,k,pForStr[i++]);
}
if(!myInitForcal()) return; //初始化Forcal
GetRunErr(ErrType,FunName,ErrCode,ForType,ForHandle); //设置运行错误为无错状态
wcout.imbue(locale("chs")); //设置输出的locale为中文
wcout<<L"字符串源代码:\r\n\r\n"<<FcStr<<endl;
ErrCode=ComModule(FcStr,nModule,hModule,ErrBegin,ErrEnd); //编译模块
if(ErrCode)
{
cout<<"表达式有错误!错误代码:"<<ErrCode<<endl;
}
else
{
vv=myDllMessage;
InsertKey("FcMessage",9,FC_Key_User,myDllMessage,NULL,vv); //使MForcal可输出信息
ExeModule(hModule,outl,outd,outc); //执行模块
wcout<<endl;
GetRunErr(ErrType,FunName,ErrCode,ForType,ForHandle); //检查运行错误
if(ErrType) wcout<<L"出现运行错误!错误类型:"<<ErrType<<L";出错函数名:"<<FunName<<L";错误代码:"<<ErrCode<<endl;
DeleteModule(hModule); //销毁模块
}
myFreeForcal(); //释放Forcal
}
版权所有© Forcal程序设计
2002-2010,保留所有权利
E-mail: forcal@sina.com
QQ:630715621
最近更新:
2010年08月22日