欢迎访问 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日