欢迎访问 Forcal程序设计

在软件中加入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日