欢迎访问 Forcal数学软件

FORCAL.DLL V7.0 编程指南

目  录

1 输出函数
2 简单计算
3 FORCAL二级函数设计
4 FORCAL的基本用法
5 用FORCAL保存和检索数据

    FORCAL用Win32标准函数调用方式(stdcall调用协议)输出了动态库函数,可供C/C++、VB、delphi、FORTRAN等程序使用。

    除了GetRunErr()、TestRunErr()和SetRunErr()三个函数外,其余的函数只能在单线程中使用(不允许两个及两个以上的线程同时运行这些函数),在设计多线程应用程序时必须注意这一点。

    在以下的说明中,fcINT被定义为长整型long,即:

    typedef long fcINT;

1 输出函数 [返回页首]

1.1 版本信息函数

    const char * _stdcall ForcalVer(void);

1.2 初始化FORCAL

    bool _stdcall InitForcal(void);

    在使用Forcal前必须先用该函数进行初始化。初始化成功时返回true,否则返回false。
    可在任何时刻使用该函数对Forcal进行重新初始化,使Forcal恢复到第一次调用该函数时的状态。

1.3 释放FORCAL

    void _stdcall FreeForcal(void);

    只要使用了FORCAL动态库函数,在卸载动态库之前,必须用该函数释放动态库。

1.4 获得FORCAL运行错误

    void _stdcall GetRunErr(int &ForType,char *&FunName,int &ErrCode);

    ForType返回运行错误的类型。ForType=0:没有运行错误;ForType=1:整数表达式运行错误;ForType=2:实数表达式运行错误;ForType=3:复数表达式运行错误;ForType=4:父表达式被删除,父表达式即该表达式中所调用的表达式,也称基表达式;ForType=5:该表达式中所调用的二级函数被删除;ForType=其它值:其它类型运行错误。
    FunName:当ForType=1、ForType=2或ForType=3时,返回出错函数名。当ForType=4或ForType=5时,返回表达式名称。
    ErrCode:当ForType=1、ForType=2或ForType=3时,返回错误代码。当ForType=4或ForType=5时,返回当前运行的表达式的类型,ErrCode=1表示整数表达式,ErrCode=2表示实数表达式,ErrCode=3表示复数表达式。

    FORCAL在运行时,将记录出现的第一个运行错误。
    通常在编译表达式前后和执行表达式前后使用该函数。使用该函数后,FORCAL将恢复为无错状态。
    在编译和执行表达式后使用该函数,是为了检测发生的运行错误。之所以还要在编译和执行表达式前使用该函数(在编译和执行表达式前,应保证没有运行错误,如果确信无错,也可以不用该函数),是因为该函数可将FORCAL恢复为无错状态;当然,也可以用SetRunErr()函数直接设为无错状态。

1.5 测试FORCAL运行错误

    int _stdcall TestRunErr(void);

    该函数返回FORCAL运行错误的类型,当返回0时表示没有错误。该函数仅仅测试是否有运行错误,并不改变错误的状态。
    通常在二级函数设计中要用到该函数。

1.6 设置FORCAL运行错误

    void _stdcall SetRunErr(int ForType,char *FunName,int ErrCode );

    ForType:设置运行错误的类型。ForType=1:整数表达式运行错误; ForType=2:实数表达式运行错误; ForType=3:复数表达式运行错误; 不要设置ForType=4或ForType=5,这两个值由系统自动设置;ForType=其它值:其它类型运行错误。
    FunName:设置出错的函数名。
    ErrCode:设置错误代码。

    在设计自定义的二级函数时,可以用该函数设置FORCAL运行错误。由于FORCAL只保存出现的第一个运行错误,因此在设置之前,先用TestRunErr(stdTestRunErr)函数测试是否出现过运行错误,如果还没有出现,可以进行设置,否则,不能进行设置。

    FORCAL允许另一个线程修改运行时的出错状态,以便退出FORCAL运行,因此可在其它线程中使用SetRunErr()函数设置运行错误。

1.7 编译实数表达式

    int _stdcall RealCom(char *ForStr,fcINT nModule,void *&hFor,fcINT &nPara,double *&Para,fcINT &ErrBegin,fcINT &ErrEnd);

    ForStr:字符串表达式。
    nModule:模块号。每一个模块都有自己的模块变量空间,为了提高存储效率,编译时尽量减少模块的数目。
    hFor:表达式句柄,标识一个表达式,计算表达式的值时要用到该参数。该参数必须为变量,不能为常量。
    nPara:该参数必须为变量,不能为常量。该参数返回表达式的自变量个数。当nPara=-1时表示有0个自变量,当nPara=0时表示有1个自变量,当nPara=1时表示有2个自变量,依次类推。
    Para:该参数必须为变量,不能为常量。该参数返回用于输入自变量的数组指针。计算表达式的值时要用到该参数。当然,也可以不用该参数,而用自己的数组输入自变量。
    ErrBegin:该参数必须为变量,不能为常量。该参数返回出错的初始位置。
    ErrEnd:该参数必须为变量,不能为常量。该参数返回出错的结束位置。
    该函数返回编译代码,当返回值为0时,表示没有错误,当返回其它值时,表示存在编译错误,出错位置由ErrBegin和ErrEnd确定。编译错误代码的意义如下:

    -1:在共享版中,编译表达式的长度受到限制!
    0:没有错误,编译成功!
    1:内存分配失败!
    2:括号不成对!
    3:(等号后)没有表达式!
    4:复数表达式中不能使用i作为参数!
    5:字符串中转义字符错误!
    6:字符串无效,即"..."不匹配!
    7:不可识别字符!
    8:表达式名称定义错误!
    9:不可识别的自变量,自变量只能以字母或下画线开头!
    10:不可识别的自变量定义方法,“(,:,:,:,:,...)”冒号过多!
    11:自变量定义错误!
    12:continue()函数只能有0个参数!
    13:只能在while,until中使用continue函数!
    14:break()函数只能有0个参数!
    15:只能在while,until中使用break函数!
    16:if,while,until,which中的参数个数至少为2个!
    17:表达式中的数字错误!
    18:&单目取地址运算符只能用于单独的变量!
    19:单目运算符++、--错误!
    20:括号内没有数字!
    21:单目运算符+、-、!错误!
    22:赋值“=”错误!
    23:不正确的运算方式或其他语法错误!
    24:不可识别变量名!
    25:不可识别函数名!
    26:一级函数只能有一个参数!
    27:二级函数参数不匹配!
    28:关键字Static或Common的位置非法!
    29:(模块中)表达式有重名!
    30:***未定义***!
    31:***未定义***!
    32:调用整数表达式时参数不匹配!
    33:调用实数表达式时参数不匹配!
    34:调用复数表达式时参数不匹配!
    35:自变量重名!
    36:因检测到运行错误而退出!

    通常在编译前用SetRunErr()函数或GetRunErr()函数使FORCAL处于无错状态,编译后用GetRunErr()检测运行错误。其他线程的错误设置可使FORCAL退出漫长的编译过程,返回错误代码36。

    FORCAL支持表达式的模块化编译。在用FORCAL编译表达式时,要给该表达式指定一个模块号,模块号用整数进行标识。

    在FORCAL中,一个模块由一个或多个表达式组成。模块用一个整数标识,整数可正可负,只要绝对值相等,就属于同一个模块。一般用正整数表示该模块名。模块共有两类,即主模块(0#模块)和普通模块(其他标号的模块)。

    同一模块中,模块号为负的表达式只能访问(即调用)本模块的表达式,同时也只有本模块的表达式能访问到,模块号为正的表达式,既可以访问本模块内的表达式,也可以访问其他模块中(主模块除外)所有模块号为正的表达式。FORCAL的这种规定说明,具有负模块号的表达式在其他模块中是不可见的,起到了信息保护的作用。

    FORCAL规定,主模块可以访问本模块中或其他模块中所有模块号为正的表达式。因此,主模块常常用在主程序中。

1.8 计算实数表达式的值

    double _stdcall RealCal(void *hFor,double *d);

    计算实数表达式hFor,hFor是实数表达式的句柄;数组d中依次存放自变量,参数d不可为NULL。可以用任意的数组存放自变量参数。
    注意自变量可能被重新赋值。可以用
ParaModify()函数判断一个表达式的自变量是否重新赋值。
    通常在计算前用SetRunErr()函数或GetRunErr()函数使FORCAL处于无错状态,计算后用GetRunErr()检测运行错误。

1.9 编译整数表达式

    int _stdcall IntCom(char *ForStr,fcINT nModule,void *&hFor,fcINT &nPara,fcINT *&Para,fcINT &ErrBegin,fcINT &ErrEnd);

    ForStr:字符串表达式。
    nModule:模块号。每一个模块都有自己的模块变量空间,为了提高存储效率,编译时尽量减少模块的数目。
    hFor:表达式句柄,标识一个表达式,计算表达式的值时要用到该参数。该参数必须为变量,不能为常量。
    nPara:该参数必须为变量,不能为常量。该参数返回表达式的自变量个数。当nPara=-1时表示有0个自变量,当nPara=0时表示有1个自变量,当nPara=1时表示有2个自变量,依次类推。
    Para:该参数必须为变量,不能为常量。该参数返回用于输入自变量的数组指针。计算表达式的值时要用到该参数。当然,也可以不用该参数,而用自己的数组输入自变量。
    ErrBegin:该参数必须为变量,不能为常量。该参数返回出错的初始位置。
    ErrEnd:该参数必须为变量,不能为常量。该参数返回出错的结束位置。
    该函数返回编译代码,当返回值为0时,表示没有错误,当返回其它值时,表示存在编译错误,出错位置由ErrBegin和ErrEnd确定。
    通常在编译前用SetRunErr()函数或GetRunErr()函数使FORCAL处于无错状态,编译后用GetRunErr()检测运行错误。

    其它请参考“1.7 编译实数表达式”中的说明。

1.10 计算整数表达式的值

    fcINT _stdcall IntCal(void *hFor,fcINT *d);

    计算整数表达式hFor,hFor是整数表达式的句柄;数组d中依次存放自变量,参数d不可为NULL。可以用任意的数组存放自变量参数。
    注意自变量可能被重新赋值。可以用
ParaModify()函数判断一个表达式的自变量是否重新赋值。
    通常在计算前用SetRunErr()函数或GetRunErr()函数使FORCAL处于无错状态,计算后用GetRunErr()检测运行错误。

1.11 编译复数表达式

    int _stdcall ComplexCom(char *ForStr,fcINT nModule,void *&hFor,fcINT &nPara,_complex *&Para,fcINT &ErrBegin,fcINT &ErrEnd);

    ForStr:字符串表达式。
    nModule:模块号。每一个模块都有自己的模块变量空间,为了提高存储效率,编译时尽量减少模块的数目。
    hFor:表达式句柄,标识一个表达式,计算表达式的值时要用到该参数。该参数必须为变量,不能为常量。
    nPara:该参数必须为变量,不能为常量。该参数返回表达式的自变量个数。当nPara=-1时表示有0个自变量,当nPara=0时表示有1个自变量,当nPara=1时表示有2个自变量,依次类推。
    Para:该参数必须为变量,不能为常量。该参数返回用于输入自变量的数组指针。计算表达式的值时要用到该参数。当然,也可以不用该参数,而用自己的数组输入自变量。
    ErrBegin:该参数必须为变量,不能为常量。该参数返回出错的初始位置。
    ErrEnd:该参数必须为变量,不能为常量。该参数返回出错的结束位置。
    该函数返回编译代码,当返回值为0时,表示没有错误,当返回其它值时,表示存在编译错误,出错位置由ErrBegin和ErrEnd确定。
    通常在编译前用SetRunErr()函数或GetRunErr()函数使FORCAL处于无错状态,编译后用GetRunErr()检测运行错误。

    其它请参考“1.7 编译实数表达式”中的说明。

1.12 计算复数表达式的值

    _complex _stdcall ComplexCal(void *hFor,_complex * d);

    计算复数表达式hFor,hFor是复数表达式的句柄;数组d中依次存放自变量,参数d不可为NULL。可以用任意的数组存放自变量参数。
    注意自变量可能被重新赋值。可以用
ParaModify()函数判断一个表达式的自变量是否重新赋值。
    通常在计算前用SetRunErr()函数或GetRunErr()函数使FORCAL处于无错状态,计算后用GetRunErr()检测运行错误。

1.13 设置外部二级函数

    int _stdcall SetFunction(fcINT FunType,char *FunName,void *Fun,fcINT ParaNum);

    FunType:二级函数类型。只能取Key_IntFunction(标识整数二级函数)、Key_RealFunction(标识实数二级函数)、Key_ComplexFunction(标识复数二级函数)。这三个标识符的值在头文件FORCAL7.h中定义。
    FunName:二级函数名称,要符合Forcal标识符的命名规定。
    Fun:二级函数指针。整数、实数、复数二级函数的函数说明格式如下:

      fcINT IntFun(fcINT m,fcINT *Para,void *hFor);          //FORCAL标准整数二级函数;
      double RealFun(fcINT m,double *Para,void *hFor);       //FORCAL标准实数二级函数;
      _complex ComplexFun(fcINT m,_complex *
Para,void *hFor);//FORCAL标准复数二级函数;

    其中m为Forcal传递给该函数的实际的参数个数,-1表示有0个自变量,0表示有1个自变量,依次类推。Para为存放参数的数组。hFor为调用该函数的表达式句柄(与编译表达式时返回的表达式句柄并不相同)。
    在FORCAL表达式中,函数的一般形式为FunName(X1,X2,...,Xn)。
    ParaNum:存放二级函数的自变量个数。数组ParaNum的对应项存放每个函数的自变量个数,其中-2表示有不确定的多个自变量,-1表示有0个自变量,0表示有1个自变量,依次类推。
    该函数返回值的意义如下:

      0:设置成功。
      1:已存在该函数。
      2:内存分配失败。
      3:不能用空字符串作为函数名。
      4:非法的
二级函数类型标识。

    例子:

      double _stdcall asd(fcINT ,double *,void *);        //自定义实数二级函数;
     
SetFunction(Key_RealFunction,"asd",asd,2);          //设置实数二级函数;

    注意:

      1、在设计二级函数时,通常要用SetRunErr(...)向FORCAL报告运行错误。
      2、通常在初始化FORCAL之后,立即进行二级函数的设置。
      3、设计二级函数必须使用_stdcall调用协议(Win32标准函数调用方式)。

1.14 设置常量

    int _stdcall SetConst(fcINT ConstType,char *ConstName,void *ConstValue);

    ConstType:常量类型。只能取Key_IntConst(标识整数常量)、Key_RealConst(标识实数常量)、Key_ComplexConst(标识复数常量)。这三个标识符的值在头文件FORCAL7.h中定义。
    ConstStr:常量名,要符合Forcal标识符的命名规定。
   
ConstValue:指向常量的值的指针。
    该函数返回值的意义如下:

      0:设置成功。
      1:已存在该常量。
      2:内存分配失败。
      3:不能用空字符串作为常量名。
      4:非法的常量类型标识。

    例如:

      double *pi=3.14;   //设置常量的值;
      SetConst(
Key_RealConst,"pi",pi);    //设置常量;

1.15 删除常量或二级函数

    void _stdcall DeleteConstOrFunction(fcINT Type,char *Name);

    Type:常量或函数类型。只能取Key_IntConst(标识整数常量)、Key_RealConst(标识实数常量)、Key_ComplexConst(标识复数常量)、Key_IntFunction(标识整数二级函数)、Key_RealFunction(标识实数二级函数)、Key_ComplexFunction(标识复数二级函数)。这六个标识符的值在头文件FORCAL7.h中定义。
    Name:
常量或函数名称,要符合Forcal标识符的命名规定。

1.16 判断一个表达式是否有效

    bool _stdcall IsFor(char *ForName,fcINT ForType,fcINT nModule,void *hFor,void *Para,fcINT PareNum);

    ForName:表达式的名称。
    ForType:表达式的类型。只能取Key_IntFor(标识整数表达式)、Key_RealFor(标识实数表达式)、Key_ComplexFor(标识复数表达式)。这三个标识符的值在头文件FORCAL7.h中定义。
    nModule:表达式所属的模块。
    hFor:表达式句柄,该句柄与编译表达式得到的表达式句柄的类型相同,可用于表达式的计算。
    Para:存放表达式自变量的数组指针。
    ParaNum:表达式自变量的个数。
    该函数返回true时表达式有效,返回false不是一个有效的表达式。

1.17 获得表达式信息

    bool _stdcall GetFor(char *ForName,fcINT ForType,void *hFor,fcINT &nModule,void *&myFor,void *&Para,fcINT &PareNum);

    ForName:所查询的表达式的名称。
    ForType:所查询的表达式的类型。只能取Key_IntFor(标识整数表达式)、Key_RealFor(标识实数表达式)、Key_ComplexFor(标识复数表达式)。这三个标识符的值在头文件FORCAL7.h中定义。
    hFor:从二级函数获得的表达式句柄。不能使用编译表达式得到的表达式句柄。
    nModule:该参数必须为变量,不能为常量。该参数返回一个表达式所属的模块。
    myFor:该参数必须为变量,不能为常量。该参数返回一个表达式句柄,该句柄与编译表达式得到的表达式句柄的类型相同,可用于表达式的计算。
    Para:该参数必须为变量,不能为常量。该参数返回一个存放表达式自变量的数组指针,可用于输入自变量。
    ParaNum:该参数必须为变量,不能为常量。该参数返回表达式自变量的个数。当ParaNum=-1时表示有0个自变量,当ParaNum=0时表示有1个自变量,当ParaNum=1时表示有2个自变量,依次类推。
    该函数返回true时查询成功,否则返回false。
    注意:只能在二级函数中使用该函数。

1.18 判断表达式的自变量是否重新赋值

    bool _stdcall ParaModify(fcINT ForType,void *vFor);

    ForType:所查询的表达式的类型。只能取Key_IntFor(标识整数表达式)、Key_RealFor(标识实数表达式)、Key_ComplexFor(标识复数表达式)。这三个标识符的值在头文件FORCAL7.h中定义。
    vFor:编译表达式时得到的表达式句柄。
    若表达式的自变量重新赋值,该函数返回true,否则返回false。
    该函数不能判断是否对局部变量或全局变量进行了赋值。

    在设计某些程序时,如果在表达式中不对自变量进行重新赋值,可以简化程序的设计,并可加快程序的执行速度。对表达式有此要求者可用该函数进行判断。

1.19 获得表达式中的字符串

    void _stdcall GetForStr(void *hFor,char *&ForStr,fcINT &StrMax);

    hFor:从二级函数获得的表达式句柄。不能使用编译表达式得到的表达式句柄。
    ForStr:该参数必须为变量,不能为常量。该参数返回一个字符串指针,表达式中的所有字符串的首地址都可由该指针加一个整数得到。表达式中的所有字符串都是连续存放的。
    StrMax:该参数必须为变量,不能为常量。该参数返回表达式中所有字符串的总长度。
    注意:只能在二级函数中使用该函数。

1.20 获得数组信息

    bool _stdcall GetArray(fcINT ArrayType,char *ArrayName,void *&Array,fcINT &ArrayMax);

    ArrayType:数组类型。只能取Key_IntArray(标识一维整数数组)、Key_RealArray(标识一维实数数组)、Key_ComplexArray(标识一维复数数组)、Key_Str(标识一维字符数组,即:字符串)。这三个标识符的值在头文件FORCAL7.h中定义。
    ArrayName:数组名。
    Array:该参数必须为变量,不能为常量。该参数返回一个数组指针。
    ArrayMax:该参数必须为变量,不能为常量。该参数返回数组的长度。

1.21 删除一个表达式

    void _stdcall DeleteFor(fcINT ForType,void *hFor);

    ForType:表达式类型。只能取Key_IntFor(标识整数表达式)、Key_RealFor(标识实数表达式)、Key_ComplexFor(标识复数表达式)。这三个标识符的值在头文件FORCAL7.h中定义。
    hFor
:表达式句柄,该句柄为编译表达式时获得的句柄。

1.22 插入一个键

    int _stdcall InsertKey(char *KeyStr,fcINT KeyType,void *KeyValue,void (_stdcall *DelKey)(void *),void *&NowKey);

    KeyStr:键的名称。不区分大小写。
    KeyType:用户自定义键的类型。KeyType>=FC_Key_User(公有键、普通键) 或者 KeyType<=FC_PrivateKey_User(私有键)约定用FC_Key_UserFC_PrivateKey_User保存一些特殊的数据,作为多个函数、线程、动态库等之间联系的通道。FC_Key_UserFC_PrivateKey_User在头文件FORCAL7.h中定义。
   
KeyValue:键值。由用户定义,标识某种数据类型。
    DelKey:删除该键值的函数指针。该函数由用户定义,但由Forcal调用,即:DelKey(KeyValue); 可将KeyValue删除。如果不需要Forcal删除该键值,该参数可设为NULL
    NowKey:该参数必须为变量,不能为常量。存在同名同类型的键时,如果NowKey=0,不更新键值,该参数返回已存在的键值;如果NowKey!=0,且KeyType<=FC_PrivateKey_User(私有键),同时新键和老键的删除函数不相同,不更新键值;其余情况下更新键值。即:

    NowKey=0,不更新键值,NowKey返回已存在的键值。
    NowKey!=0,且KeyType>=FC_Key_User:更新键值。
    NowKey!=0,且KeyType<=FC_PrivateKey_User,新键和老键的删除函数相同:更新键值。
    NowKey!=0,且KeyType<=FC_PrivateKey_User,新键和老键的删除函数不相同:不更新键值NowKey返回已存在的键值

    该函数返回值的意义如下:

      0:插入成功。
      1:已存在该键。参数
NowKey=0,没有更新键值,由参数NowKey返回已存在的键值。或者NowKey!=0,KeyType<=FC_PrivateKey_User(私有键),且新键和老键的删除函数不相同,没有更新键值,参数NowKey返回了已存在的键值。
      2:已存在该键。参数
NowKey!=0,当KeyType>=FC_Key_User时,更新了键值;或者当KeyType<=FC_PrivateKey_User(私有键),且新键和老键的删除函数相同时,更新了键值。
      3:键的类型参数
KeyType非法。
      4:键值类型被唯一指定,删除该键值的函数指针
DelKey非法,必须使用被唯一指定的函数指针。
      5:内存分配失败。
      6:不能用空字符串作为键的名称。

1.23 查找一个键

    void * _stdcall SearchKey(char *KeyStr,fcINT KeyType);

    KeyStr:键的名称。不区分大小写。
    KeyType:用户自定义键的类型。KeyType>=FC_Key_User 或者 KeyType<=FC_PrivateKey_UserFC_Key_UserFC_PrivateKey_User在头文件FORCAL7.h中定义。
    如果查找成功,该函数返回键值的指针,否则返回false。

1.24 删除一个键

    void _stdcall DeleteKey(char *KeyStr,fcINT KeyType);

    KeyStr:键的名称。不区分大小写。
    KeyType:用户自定义键的类型。该类型值的最小值为FC_Key_UserFC_Key_User在头文件FORCAL7.h中定义。

1.25 删除一个私有键

    void _stdcall DeletePrivateKey(char *KeyStr,fcINT KeyType,void (_stdcall *DelKey)(void *));

    KeyStr:键的名称。不区分大小写。
   
KeyType:用户自定义键的类型。该类型值的最大值为FC_PrivateKey_UserFC_PrivateKey_User在头文件FORCAL7.h中定义。
   
DelKey:删除该键值的函数指针。该指针与插入键时用到的函数指针相同,否则不能删除键值。

1.26 枚举指定键值类型所对应的所有字符串及键值

    void _stdcall EnumKeyTypeValue(fcINT KeyType,char *KeyStr,int nKeyStrMax,bool (_stdcall *GetKeyTypeValue)(char *,bool ,void *));

    KeyType:指定键的类型。KeyType>=FC_Key_User(公有键、普通键) 或者 KeyType<=FC_PrivateKey_User(私有键)FC_Key_UserFC_PrivateKey_User在头文件FORCAL7.h中定义。
   
KeyStr:存放键的名称的缓冲区。如果缓冲区不够用,仅存放键的名称的前面部分字符。
   
nKeyStrMax:存放键的名称的缓冲区的最大长度(nKeyStrMax>=1)。
   
GetKeyTypeValue:回调函数。每当找到指定键的类型对应的键时就调用该函数。该回调函数的说明格式如下:

      bool _stdcall GetKeyTypeValue(char *KeyStr,bool bFull,void *KeyValue);
      KeyStr:键的名称。
     
bFull:指出键的名称的完整性。bFull=true时,键的名称是完整的;bFull=false时,键的名称不完整,仅存放了名称的前面部分字符。使用更大的缓冲区可使该函数返回键的完整名称。
     
KeyValue:键值。标识某种数据类型。
      当
GetKeyTypeValue返回true时,继续枚举其他键值,否则停止枚举。
      注意:不要在该函数中调用除了GetRunErr()、
TestRunErr()和SetRunErr()三个函数之外的Forcal输出函数。

1.27 锁定键的类型

    int _stdcall LockKeyType(fcINT KeyType,void (_stdcall *DelKey)(void *),void (_stdcall *NullLock)(void));

    KeyType:被锁定的键的类型。KeyType>=FC_Key_User(公有键、普通键) 或者 KeyType<=FC_PrivateKey_User(私有键)FC_Key_UserFC_PrivateKey_User在头文件FORCAL7.h中定义。
   
DelKey:删除键值的函数指针,用于标识要加锁的键。该函数由用户定义,但由Forcal调用。若DelKeyNULL,表示解锁指定的键。
   
NullLock:有效的函数指针,该函数仅在加锁或解锁键的类型时被调用一次,一般将该函数设置为空函数。解锁和加锁所用的NullLock函数必须相同。
    如果加锁或解锁成功,该函数返回0,否则返回非0值。
    说明:锁定键的类型后,该键只能存储一种数据类型,该数据类型用删除函数标识。如果没有锁定键的类型,则该键可以存储任意多种类型的数据。只有欲加锁的键没有使用,也没有存储任何类型的数据时,才能将该键加锁;解锁时将删除所有的键值,将键恢复为加锁前未用时的状态。通常在主调程序中锁定的键无需解锁,Forcal会自动删除键树中的所有数据。在动态库中锁定的键必须解锁,否则将导致不可预知的错误。

1.28 与Forcal交换信息

    void * _stdcall ExMsgWithForcal(fcINT Type,void *hMsg,void *&Msg1,void *&Msg2);

    Type: 输入参数,信息交换的类型。
   
hMsg:输入参数,信息句柄,其意义取决于Type
   
Msg1:该参数必须为变量,不能为常量。输入值及返回值取决于Type
   
Msg2:该参数必须为变量,不能为常量。输入值及返回值取决于Type
    返回值:NULL表示失败,非0值表示成功。成功时返回值的意义取决于
Type
    说明:与Forcal进行信息交换,向Forcal传送信息或者从Forcal获得信息。信息的类型及意义如下表所示:

Type hMsg Msg1 Msg2 返回值 说明
1 从二级函数获得的表达式句柄

返回表达式类型:
Msg1=1:整数表达式
Msg1=2:实数表达式
Msg1=3:复数表达式

返回表达式句柄 指向表达式名称的字符串指针 得到表达式名称、类型、句柄
2 编译表达式得到的表达式句柄

输入表达式类型:
Msg1=1:整数表达式
Msg1=2:实数表达式
Msg1=3:复数表达式

无意义 指向表达式名称的字符串指针 得到表达式名称
3 从二级函数获得的表达式句柄

返回表达式类型:
Msg1=1:整数表达式
Msg1=2:实数表达式
Msg1=3:复数表达式

返回表达式句柄 表达式模块号 得到表达式模块号、类型、句柄
4 编译表达式得到的表达式句柄

输入表达式类型:
Msg1=1:整数表达式
Msg1=2:实数表达式
Msg1=3:复数表达式

无意义 表达式模块号 得到表达式模块号
11 字符串指针 无意义 无意义 指向整数常量的指针 得到Forcal中的整数常量
12 字符串指针 无意义 无意义 指向实数常量的指针 得到Forcal中的实数常量
13 字符串指针 无意义 无意义 指向复数常量的指针 得到Forcal中的复数常量

2 简单计算 [返回页首]

2.1 使用FORCAL进行简单的整数计算

    1、用InitForcal()初始化Forcal;
    2、用
IntCom(char *ForStr,fcINT nModule,void *&hFor,fcINT &nPara,fcINT *&Para,fcINT &ErrBegin,fcINT &ErrEnd)编译表达式,模块号nModule根据实际情况设置;
    3、用
IntCal(void *hFor,fcINT *d)计算表达式;
    4、用FreeForcal()释放Forcal。

2.2 使用FORCAL进行简单的实数计算

    1、用InitForcal()初始化Forcal;
    2、用
RealCom(char *ForStr,fcINT nModule,void *&hFor,fcINT &nPara,double *&Para,fcINT &ErrBegin,fcINT &ErrEnd)编译表达式,模块号nModule根据实际情况设置;
    3、用
RealCal(void *hFor,double *d)计算表达式;
    4、用FreeForcal()释放Forcal。

2.3 使用FORCAL进行简单的复数计算

    1、用InitForcal()初始化Forcal;
    2、用
ComplexCom(char *ForStr,fcINT nModule,void *&hFor,fcINT &nPara,_complex *&Para,fcINT &ErrBegin,fcINT &ErrEnd)编译表达式,模块号nModule根据实际情况设置;
    3、用
ComplexCal(void *hFor,_complex *d)计算表达式;
    4、用FreeForcal()释放Forcal。

2.4 使用FORCAL进行简单的实数、整数和复数计算

    1、用InitForcal()初始化Forcal。

    2、编译表达式

      用IntCom(char *ForStr,fcINT nModule,void *&hFor,fcINT &nPara,fcINT *&Para,fcINT &ErrBegin,fcINT &ErrEnd)编译整数表达式,模块号nModule根据实际情况设置;
      用
RealCom(char *ForStr,fcINT nModule,void *&hFor,fcINT &nPara,double *&Para,fcINT &ErrBegin,fcINT &ErrEnd)编译实数表达式,模块号nModule根据实际情况设置;
      用
ComplexCom(char *ForStr,fcINT nModule,void *&hFor,fcINT &nPara,_complex *&Para,fcINT &ErrBegin,fcINT &ErrEnd)编译复数表达式,模块号nModule根据实际情况设置;

    3、计算表达式

      用IntCal(void *hFor,fcINT *d)计算整数表达式;
      用
RealCal(void *hFor,double *d)计算实数表达式;
      用
ComplexCal(void *hFor,_complex *d)计算复数表达式;

    4、用 FreeForcal() 释放Forcal。

3 FORCAL二级函数设计 [返回页首]

    以设计实数二级函数为例进行说明,复数、整数的二级函数设计与此类似。

    二级函数的一般形式是:

      double _stdcall Fun2Name(fcINT n,double *d,void *hFor);

    相应地,在表达式中二级函数的使用形式是

      Fun2Name(X1,X2,... ...,Xn)

    数组d中依次存放各个自变量X1,X2,... ...,Xn;整数n指出自变量的个数,其大小为自变量的个数减1。

    hFor是由Forcal传送过来的调用该二级函数的表达式的句柄,该句柄与编译表达式所获得的句柄不同。由该句柄可以获得更多的信息。

    以下是二级函数设计中可能用到的FORCAL输出函数及注意事项:

    1、用GetForStr(...)函数获得表达式中的字符串。该函数只能在二级函数内部使用。
    2、用GetFor(...)函数获得各个表达式并进行计算。该函数只能在二级函数内部使用。
    3、用GetArray(...)获得FORCAL数组并进行操作。
    4、用
TestRunErr(void)测试是否有运行错误。由于FORCAL允许另一个线程修改运行时的出错状态,以便退出FORCAL运行,因此在二级函数设计中,在可能导致无限循环的循环体内,要使用TestRunErr()函数检测运行错误,如果检测到任何错误,就退出该二级函数。
    5、用
SetRunErr(...)设置外部函数的运行错误。

4 FORCAL的基本用法 [返回页首]

    尽管FORCAL表达式的用法可以非常灵活,但以下两种用法可能是最基本的。

4.1 动态使用字符串表达式

    程序在运行过程中,动态地使用字符串表达式并进行计算。例如根据需要计算字符串数学表达式的值,或者执行一定的命令等。

    在这种方法中,对于一种特定的运算,仅在需要的时候使用FORCAL,而其他的代码要用C/C++或FORTRAN等高级语言来写。

    用这种方法得到的数值计算程序,其执行速度约为C/C++或FORTRAN执行速度的50%左右。但程序一经生成,即可脱离高级语言编译器独立运行,象使用Matlab和Mathematics一样方便。

4.2 按次序依次执行表达式进行运算

    这是用FORCAL进行编程的一种方式。程序文件中的表达式用分隔符(通常用分号“;”)分隔,按某种次序依次编译各个表达式,编译成功后,按编译次序依次执行各个表达式。

    无论哪种使用方式,在编译表达式前后和计算表达式前后都要检查FORCAL运行错误。

    Forcal始终记着编译过的表达式,这使得同名的表达式将不能再被编译,除非你释放了该表达式所占据的空间。可以用DeleteFor(...)函数释放一个表达式所占据的空间。如果使用初始化函数InitForcal(),将连同注册的二级函数、常量、申请的数组、注册的所有自定义数据等一并删除。

5 用FORCAL保存和检索数据  [返回页首]

    Forcal用多键值字符串键树保存和检索数据信息,具有存储效率高、查询速度快的优点。用户可将自定义的数据信息保存到该键树中,并与Forcal融为一体。用户可通过InsertKey(...)、SearchKey(...)、DeleteKey(...)、DeletePrivateKey(...)等函数往键树中插入、查询和删除数据信息。


版权所有© Forcal数学软件 2002-2008,保留所有权利
E-mail: forcal@sina.com
  QQ:630715621
最近更新: 2008年05月01日