通用FORCAL脚本系统GForcal(General Forcal DLL)
目 录
2.1 GForcal中的输出函数 | 函数虽多,但常用的也许只有几个。 |
2.2 Forcal脚本中可用的函数 | 在主程序和Forcal脚本之间用于数据交换的函数。 |
3 例子 | |
例子3.1~3.5的C#示例代码 | 感谢刘圆圆先生(mgenx@live.com)为例子3.1~3.5编写了C#代码,下载:http://www.forcal.net/xiazai/forcal9/forcal9code.rar |
3.1 使用缺省方式执行模块 | 演示如何按缺省方式编译运行一段Forcal源代码,并获得运行结果。 |
3.2 使用自定义方式执行模块 | 演示如何按自定义方式编译运行一段Forcal源代码,并输出运行结果。 |
3.3 使用Forcal脚本中的全局函数 | 演示如何使用Forcal中定义的全局函数。这样可方便地与Forcal系统中的静态变量、模块变量以及全局变量进行交互,这些变量可以是任意的对象。 |
3.4 操作Forcal系统中的数组对象 | 演示如何操作Forcal系统中的数组对象,同时也演示如何加载使用Forcal扩展库。 |
3.5 通过GForcal的输出函数交互数据 | 演示如何通过GForcal的输出函数与Forcal系统交互数据。 |
3.6 操作来自Forcal扩展库中的任意对象 | 只要知道对象的标识和对象的定义,就可以方便地进行操作。 |
1 什么是GForcal [返回页首]
GForcal32W.dll是一个通用的Forcal脚本系统(简称GForcal)。GForcal可看作应用程序与Forcal之间的一个接口,但GForcal简化了Forcal脚本的使用。
GForcal至少需要三个dll的支持:Forcal核心库Forcal32W.dll、Forcal模块化编译运行库MForcal32W.dll和Forcal数据类型扩展动态库FcData32W.dll。这三个支持库的位置比较灵活:(1)与GForcal32W.dll放在一起;(2)放在GForcal32W.dll所在文件夹的子文件夹“FcDll”中;(3)放在Windows搜索目录。
通过GForcal,可动态地加载和卸载任意多个Forcal扩展库,灵活地使用Forcal脚本系统。
GForcal支持在多线程中使用Forcal的功能。GForcal内置了一个Forcal运行监视器,以方便用户从无限循环中退出。
任意程序加载GForcal后,可以:动态定义函数,供程序使用;动态对指定的对象进行操作,并获得结果;无限的功能扩展。
2 GForcal中的函数 [返回页首]
2.1 GForcal中的输出函数
函 数 | 说 明 | 来 源 | 是否需要UseForcal |
InitGForcal | 初始化GForcal。 | GForcal | 否 |
FreeGForcal | 释放GForcal。 | GForcal | 否 |
GetInstance | 得到Forcal32W.dll、MForcal32W.dll和FcData32W.dll的句柄。 | GForcal | 否 |
GetProcAddr | 通过动态库句柄和函数名获得动态库的输出函数。 | GForcal | 否 |
LoadDll | 加载Forcal扩展动态库。 | GForcal | 否 |
FreeDll | 释放Forcal扩展动态库。 | GForcal | 否 |
ReInitGFC | 重新初始化GForcal。 | GForcal | 否 |
GetRunErr | 获得FORCAL运行错误 | Forcal | 否 |
TestRunErr | 测试FORCAL运行错误 | Forcal | 否 |
SetRunErr | 设置FORCAL运行错误 | Forcal | 否 |
UseForcal | 申请进入或退出Forcal工作区 | MForcal | - |
ComModule | 编译源程序为一个模块 | MForcal | 是 |
ExeModule | 执行程序(模块) | MForcal | 是 |
DelModule | 删除模块 | MForcal | 是 |
SetResultBufMax | 设置自动保存运行结果的缓冲区的大小。 | GForcal | 是 |
DefExeModule | 按缺省方式执行模块,自动保存运行结果。 | GForcal | 是 |
GetResult | 获得运行结果。 | GForcal | 是 |
IsFcData | 判断是否是FcData数据 | FcData | 是 |
IntCal | 计算整数表达式的值 | Forcal | 是 |
RealCal | 计算实数表达式的值 | Forcal | 是 |
ComplexCal | 计算复数表达式的值 | Forcal | 是 |
SetFunction | 设置外部二级函数 | Forcal | 是 |
SetConst | 设置常量 | Forcal | 是 |
DeleteConstOrFunction | 删除常量或二级函数 | Forcal | 是 |
IsFor | 判断一个表达式是否有效 | Forcal | 是 |
GetFor | 获得表达式信息 | Forcal | 是 |
ParaModify | 判断表达式的自变量是否重新赋值 | Forcal | 是 |
GetForStr | 获得表达式中的字符串 | Forcal | 是 |
InsertKey | 插入一个键 | Forcal | 是 |
SearchKey | 查找一个键 | Forcal | 是 |
DeleteKey | 删除一个键 | Forcal | 是 |
DeletePrivateKey | 删除一个私有键 | Forcal | 是 |
EnumKeyTypeValue | 枚举指定键值类型所对应的所有字符串及键值 | Forcal | 是 |
LockKeyType | 锁定键的类型 | Forcal | 是 |
ExMsgWithForcal | 与Forcal交换信息 | Forcal | 是 |
SetStr | 向GForcal传送字符串。 | GForcal | 是 |
GetStr | 获得GForcal中的字符串。 | GForcal | 是 |
SetInts | 向GForcal传送整数数组。 | GForcal | 是 |
GetInts | 获得GForcal中的整数数组。 | GForcal | 是 |
SetReals | 向GForcal传送实数数组。 | GForcal | 是 |
GetReals | 获得GForcal中的实数数组。 | GForcal | 是 |
说明:
(1)许多函数需要互斥地使用Forcal资源,故这些函数在使用前,必须用函数UseForcal获得Forcal的使用权。
(2)来自Forcal32W.dll、MForcal32W.dll和FcData32W.dll中的函数,在GForcal中又加了一层包装,故速度稍慢。要获得更快的速度,可使用GetInstance和GetProcAddr函数直接获得相关函数的句柄。
[返回函数列表] InitGForcal:初始化GForcal
bool _stdcall InitGForcal(void);
说明:在使用GForcal之前必须用该函数初始化。初始化成功函数返回true。
[返回函数列表] FreeGForcal:释放GForcal
void _stdcall FreeGForcal(void);
说明:在使用完GForcal之后必须用该函数释放加载的资源。
[返回函数列表] GetInstance:得到Forcal32W.dll、MForcal32W.dll和FcData32W.dll的句柄
void _stdcall GetInstance(HINSTANCE &forcal,HINSTANCE &mforcal,HINSTANCE &fcdata);
说明:获得了这三个动态库的句柄后,可以用函数GetProcAddr获得相关动态库中的输出函数,这样可使用Forcal的全部功能,而且速度更快。
警告:不要从Forcal32W.dll中获得InitForcal和FreeForcal的函数句柄进行操作。
[返回函数列表] GetProcAddr:通过动态库句柄和函数名获得动态库的输出函数
说明:该函数与GetProcAddress的用法功能完全相同,提供该函数仅仅是为了方便使用。
[返回函数列表] LoadDll:加载Forcal扩展动态库
void _stdcall LoadDll(wchar_t *DllStr);
说明:
DllStr:含有Forcal扩展动态库名称的字符串。
允许加载多个Forcal扩展动态库。Forcal扩展动态库名字要放在双引号"..."之间。忽略在尖括号<"..." ...>内的Forcal扩展动态库。
例如:"FcMath32W","d:\\forcal\\FcSystem32W.dll"
需要注意Forcal扩展动态库的加载顺序。
[返回函数列表] FreeDll:释放Forcal扩展动态库
void _stdcall FreeDll(void);
[返回函数列表] ReInitGFC:重新初始化GForcal
void _stdcall ReInitGFC(void);
说明:使GForcal恢复至InitGForcal时的状态。
[返回函数列表] SetResultBufMax:设置自动保存运行结果的缓冲区的大小
bool _stdcall SetResultBufMax(long k);
说明:在执行函数DefExeModule时,运行结果将保存到一个缓冲区中,该函数用于设置该缓冲区的大小。
[返回函数列表] DefExeModule:按缺省方式执行模块,自动保存运行结果
void _stdcall DefExeModule(void *hModule);
说明:hModule为模块句柄。结果将保存在GForcal内置的缓冲区中。
void _stdcall GetResult(wchar_t *str, long strmax);
说明:strmax为字符串str的大小。
bool _stdcall SetStr(wchar_t *str);
说明:
在GForcal中有一个缓冲区,主程序和缓冲区可以相互传送数据。在主程序中使用该函数可以将字符串传送到该缓冲区。
该函数总是从缓冲区的起始处存放数据,也就是说,每次调用该函数,以前存放的数据都会丢失。
[返回函数列表] GetStr:获得GForcal中的字符串
bool _stdcall GetStr(wchar_t *str, long strmax);
说明:
str:接收数据的缓冲区指针。
nstr:缓冲区str的大小。
在GForcal中有一个缓冲区,主程序和缓冲区可以相互传送数据。在主程序中使用该函数可以将缓冲区中的字符串传送到str中。若strmax太小,传送失败。
该函数总是从缓冲区的起始处获得数据。
[返回函数列表] SetInts:向GForcal传送整数数组
bool _stdcall SetInts(fcIFOR *xx,long xxmax);
说明:
xxmax为整数数组xx的大小。
在GForcal中有一个缓冲区,主程序和缓冲区可以相互传送数据。在主程序中使用该函数可以将整数数组传送到该缓冲区。
该函数总是从缓冲区的起始处存放数据,也就是说,每次调用该函数,以前存放的数据都会丢失。
[返回函数列表] GetInts:获得GForcal中的整数数组
long _stdcall GetInts(fcIFOR *xx,long xxmax);
说明:
xx:接收数据的缓冲区指针。
xxmax:缓冲区xx的大小。
在GForcal中有一个缓冲区,主程序和缓冲区可以相互传送数据。在主程序中使用该函数可以将缓冲区中的整数数组传送到xx中。
该函数总是从缓冲区的起始处获得数据。该函数返回实际传送的数组元素个数。
若xx为NULL,或者xxmax<=0,函数返回当前整数数组缓冲区的大小。
[返回函数列表] SetReals:向GForcal传送实数数组
bool _stdcall SetReals(double *xx,long xxmax);
说明:
xxmax为实数数组xx的大小。
在GForcal中有一个缓冲区,主程序和缓冲区可以相互传送数据。在主程序中使用该函数可以将实数数组传送到该缓冲区。
该函数总是从缓冲区的起始处存放数据,也就是说,每次调用该函数,以前存放的数据都会丢失。
[返回函数列表] GetReals:获得GForcal中的实数数组
long _stdcall GetReals(double *xx,long xxmax);
说明:
xx:接收数据的缓冲区指针。
xxmax:缓冲区xx的大小。
在GForcal中有一个缓冲区,主程序和缓冲区可以相互传送数据。在主程序中使用该函数可以将缓冲区中的实数数组传送到xx中。
该函数总是从缓冲区的起始处获得数据。该函数返回实际传送的数组元素个数。
若xx为NULL,或者xxmax<=0,函数返回当前实数数组缓冲区的大小。
2.2 Forcal脚本中可用的函数
2.2.1 向GForcal缓冲区传送数据[整数函数,实数函数]:FcSet(&i,x1,x2,... ...,xn)
在GForcal中有一个缓冲区,缓冲区和Forcal可以相互传送数据。缓冲区是一个一维数组,起始地址为0。在Forcal中使用FcSet函数可以将数据x1,x2,... ...传送到该缓冲区自地址i开始的连续区域,函数返回下一个元素的地址(即元素xn后的地址,如果使用引用参数,i也指向该地址)。如果缓冲区没有足够的空间存放数据,该函数将自动扩充缓冲区的大小。
在整数表达式中,将把数据传送到整数缓冲区;在实数表达式中,将把数据传送到实数缓冲区。
该函数可能返回运行错误,错误代码1:非法的元素地址;2:无法分配内存。
FcSet函数的特殊用法:
FcSet(); //函数返回当前缓冲区大小
FcSet(n); //创建至少能存放n个数据元素的缓冲区
一般,先用FcSet(n)创建能满足要求的缓冲区,然后存放数据,可提高运行效率。
2.2.2 从GForcal缓冲区获得数据[整数函数,实数函数]:FcGet(&i,&x1,&x2,... ...,&xn)
在GForcal中有一个缓冲区,缓冲区和Forcal可以相互传送数据。缓冲区是一个一维数组,起始地址为0。在Forcal中使用FcGet函数可以将缓冲区中从地址i开始的数据传送到x1,x2,... ...,xn,必须使用引用参数,函数返回下一个元素的地址(即元素xn后的地址,如果使用引用参数,i也指向该地址)。
在整数表达式中,将获得整数缓冲区中的数据;在实数表达式中,将获得实数缓冲区中的数据。
该函数可能返回运行错误,错误代码1:非法的元素地址。
FcGet函数的特殊用法:FcGet(); //函数返回当前缓冲区大小
2.2.3 向GForcal缓冲区传送UNICODE字符串[整数函数]:FcSetStr(Wstr)
在GForcal中有一个UNICODE字符串缓冲区,该缓冲区可以和FcData一维wchar_s数组相互传送数据。在Forcal中使用FcSetStr函数可以将一维iwchar_s数组Wstr传送到该缓冲区,函数总是返回0。如果缓冲区没有足够的空间存放数据,该函数将自动扩充缓冲区的大小。该函数需要FcData32W.dll的支持。
在一维wchar_s数组中遇到0(UNICODE字符串结束标记)时将结束传送,如果没有0,将返回一个运行错误。
该函数可能返回运行错误,错误代码1:数组不存在;2:不是一维宽字符数组;3:内存错误;4:字符串没有结束标志0。
FcSetStr函数的特殊用法:FcSetStr(0); //函数返回当前缓冲区大小
2.2.4 从GForcal缓冲区获得UNICODE字符串[整数函数]:FcGetStr(Wstr)
在GForcal中有一个UNICODE字符串缓冲区,该缓冲区可以和FcData一维wchar_s数组相互传送数据。在Forcal中使用FcGetStr函数可以将缓冲区中的字符串传送到一维wchar_s数组Wstr,函数总是返回0。该函数需要FcData32W.dll的支持。
该函数可能返回运行错误,错误代码1:数组不存在;2:不是一维宽字符数组;3:一维宽字符数组太小。
FcGetStr函数的特殊用法:FcGetStr(0); //函数返回当前缓冲区大小
2.2.5 设置GForcal运行结果缓冲区大小[整数函数,实数函数]:SetResultBufMax(n)
该函数设置GForcal运行结果缓冲区的大小。函数总是返回实际的缓冲区大小。为了提高运行效率,一般在程序开头使用该函数。
这些例子体现了应用程序如何与Forcal系统进行交互,一般步骤是:
(1)使用函数InitGForcal进行初始化。
(2)使用函数LoadDll加载需要的Forcal扩展库。
(3)使用函数ComModule将字符串源代码编译为模块。
(4)使用函数DefExeModule或ExeModule执行模块,或者使用函数GetFor获取需要的表达式进行计算。
(5)使用函数ExMsgWithForcal获得数据类型标识,通过函数SearchKey或者IsFcData验证操作数据的类型,然后进行数据传送操作。或者使用函数SetStr、GetStr、SetInts、GetInts、SetReals、GetReals等传送数据。
(6)使用函数FreeDll卸载Forcal扩展库。
(7)使用函数FreeGForcal释放资源。
注意:许多函数需要用UseForcal获得Forcal的使用权后才能调用,用完后要及时归还Forcal使用权。
要演示这些例子,在编译时需要头文件forcal32w.h和gforcal32w.h,引入库GForcal32W.lib;在运行时需要GForcal32W.dll及支持库Forcal32W.dll、MForcal32W.dll和FcData32W.dll,以及相关Forcal扩展库的支持。
感谢刘圆圆先生(mgenx@live.com)为例子3.1~3.5编写了C#代码,下载:http://www.forcal.net/xiazai/forcal9/forcal9code.rar
3.1 使用缺省方式执行模块
本例子演示如何按缺省方式编译运行一段Forcal源代码,并获得运行结果。
C/C++源代码:
#include <windows.h>
#include <iostream>
#include <math.h>
#include "forcal32w.h"
#include "gforcal32w.h"
#pragma comment( lib, "GForcal32W.lib" )
using namespace std;
void main(void)
{
wchar_t str1[]=L"f(x,y)=x+y; 3+f(1,2); c: 2-sin[3i];"; //存放Forcal表达式
const int StrMax=100;
wchar_t str2[StrMax];
fcVOID nModule;
void *hModule;
fcINT err1,err2;
int n;
wcout.imbue(locale("chs")); //设置输出的locale为中文
wcin.imbue(locale("chs")); //设置输入的locale为中文
InitGForcal(); //初始化GForcal
if(!UseForcal(2)) //申请使用Forcal
{
nModule=0; //由MForcal自动指定模块号
n=ComModule(str1,nModule,hModule,err1,err2); //将字符串源代码编译为模块
if(n==0)
{
SetResultBufMax(StrMax); //设置存放运行结果的缓冲区
DefExeModule(hModule); //按缺省方式执行模块
GetResult(str2, StrMax); //得到运行结果
wcout<<str2; //输出运行结果
}
UseForcal(0); //归还Forcal的使用权
}
wcin.get();
FreeGForcal(); //释放GForcal
}
运行结果:
6.
c: 2.-10.0178749274099i
3.2 使用自定义方式执行模块
本例子演示如何按自定义方式编译运行一段Forcal源代码,并输出运行结果。
C/C++源代码:
#include <windows.h>
#include <iostream>
#include <math.h>
#include "forcal32w.h"
#include "gforcal32w.h"
#pragma comment( lib, "GForcal32W.lib" )
using namespace std;
void _stdcall myFcMessage(wchar_t *str) //输出一个字符串
{
wcout<<str;
}
void _stdcall outi(fcIFOR ll) //输出一个整数
{
wchar_t wchNum[32];
myFcMessage(L"\r\ni: ");
_i64tow_s(ll,wchNum,32,10);
myFcMessage(wchNum);
}
void _stdcall outd(double dd) //输出一个实数
{
char chNum[32];
wchar_t wchNum[32];
int i;
myFcMessage(L"\r\n");
_gcvt_s(chNum,32,dd,16);
for(i=0;chNum[i];i++) {wchNum[i]=chNum[i];}
wchNum[i]='\0';
myFcMessage(wchNum);
}
void _stdcall outc(_complex cc) //输出一个复数
{
char chNum[32];
wchar_t wchNum[32];
int i;
myFcMessage(L"\r\nc: ");
_gcvt_s(chNum,32,cc.x,16);
for(i=0;chNum[i];i++) {wchNum[i]=chNum[i];}
wchNum[i]='\0';
myFcMessage(wchNum);
if(cc.y!=0.0)
{
if(cc.y>0.0) myFcMessage(L"+");
_gcvt_s(chNum,32,cc.y,16);
for(i=0;chNum[i];i++) {wchNum[i]=chNum[i];}
wchNum[i]='\0';
myFcMessage(wchNum);
myFcMessage(L"i");
}
}
void main(void)
{
wchar_t str1[]=L"f(x,y)=x+y; 3+f(1,2); c: 2-sin[3i];"; //存放Forcal表达式
fcVOID nModule;
void *hModule;
fcINT err1,err2;
int n;
void *vv;
wcout.imbue(locale("chs")); //设置输出的locale为中文
wcin.imbue(locale("chs")); //设置输入的locale为中文
InitGForcal(); //初始化GForcal
if(!UseForcal(2)) //申请使用Forcal
{
nModule=0; //由MForcal自动指定模块号
n=ComModule(str1,nModule,hModule,err1,err2); //将字符串源代码编译为模块
if(n==0)
{
vv=myFcMessage;
InsertKey("FcMessage",9,FC_Key_User,myFcMessage,NULL,vv); //将函数myFcMessage注册到Forcal
ExeModule(hModule,outi,outd,outc); //执行模块
}
UseForcal(0); //归还Forcal的使用权
}
wcin.get();
FreeGForcal(); //释放GForcal
}
运行结果:
6.
c: 2.-10.0178749274099i
3.3 使用Forcal脚本中的全局函数
本例子演示了如何使用Forcal系统中定义的全局函数,但私有函数是无法获得的。通过全局函数,可以方便地与Forcal系统中的静态变量、模块变量以及全局变量进行交互,这些变量可以是任意的对象。
C/C++源代码:
#include <windows.h>
#include <iostream>
#include <math.h>
#include "forcal32w.h"
#include "gforcal32w.h"
#pragma comment( lib, "GForcal32W.lib" )
using namespace std;
void main(void)
{
wchar_t str1[]=L"f(x,y)=x+y; ~g(x,y)=3+f(x,y); ~h(x,y)=x-f(3,y);"; //存放Forcal表达式
fcVOID nModule;
void *hModule,*myFor,*Para;
fcINT err1,err2,PareNum;
double xx[2]={1,2}; //作为自变量参数
wcout.imbue(locale("chs")); //设置输出的locale为中文
wcin.imbue(locale("chs")); //设置输入的locale为中文
InitGForcal(); //初始化GForcal
if(!UseForcal(2)) //申请使用Forcal
{
nModule=0; //由MForcal自动指定模块号
ComModule(str1,nModule,hModule,err1,err2); //将字符串源代码编译为模块
if(GetFor(L"g",2,NULL,nModule,myFor,Para,PareNum)) //查找全局函数g
{
if(PareNum==1) //函数有2个自变量
{
wcout<<RealCal(myFor,xx)<<L"\r\n"; //计算并输出结果
}
}
if(GetFor(L"h",2,NULL,nModule,myFor,Para,PareNum)) //查找全局函数h
{
if(PareNum==1) //函数有2个自变量
{
wcout<<RealCal(myFor,xx); //计算并输出结果
}
}
UseForcal(0); //归还Forcal的使用权
}
wcin.get();
FreeGForcal(); //释放GForcal
}
运行结果:
6
-4
3.4 操作Forcal系统中的数组对象
本例子演示了如何操作Forcal系统中的数组对象,同时也演示了如何加载使用Forcal扩展库。演示要点如下:
(1)加载Forcal扩展库FcMath32W.dll。
(2)获取并运行了Forcal脚本中的全局函数a,该函数返回一个FcData数组对象。
(3)验证该数组对象,并赋初值。
(4)获取并运行了Forcal脚本中的全局函数b,该函数对传入的数组的每一个元素加1。
(5)验证该数组对象仍然有效,并输出最终结果。
(6)卸载Forcal扩展库。
C/C++源代码:
#include <windows.h>
#include <iostream>
#include <math.h>
#include "forcal32w.h"
#include "gforcal32w.h"
#pragma comment( lib, "GForcal32W.lib" )
using namespace std;
void main(void)
{
wchar_t str1[]=L"~a(:static,aa)= if[!aa,aa=math::array(3).free()], aa; ~b(x:i,k)= k=FCDLen(x), i=0,(i<k).while{x[i]=x[i]+1, i++};"; //存放Forcal表达式
fcVOID nModule,i;
void *hModule,*aFor,*bFor,*Para;
fcINT err1,err2,PareNum;
fcdTYPE real_s,BasicType;
FCDArrayS *pFCDArrayS;
double xx[1],x,*px;
wcout.imbue(locale("chs")); //设置输出的locale为中文
wcin.imbue(locale("chs")); //设置输入的locale为中文
InitGForcal(); //初始化GForcal
LoadDll(L"\"FcDll\\FcMath32W.dll\""); //加载Forcal扩展库
if(!UseForcal(2)) //申请使用Forcal
{
//查找注册到Forcal中的FcData实数数组类型标识
real_s=(fcdTYPE)*(fcIFOR *)ExMsgWithForcal(Key_IntConst,L"real_s",Para,Para);
nModule=0; //由MForcal自动指定模块号
ComModule(str1,nModule,hModule,err1,err2); //将字符串源代码编译为模块
if(GetFor(L"a",2,NULL,nModule,aFor,Para,PareNum)) //查找全局函数a
{
if(PareNum==-1) //函数有0个自变量
{
x=RealCal(aFor,xx); //计算结果为一个实数数组
}
}
IsFcData(*(fcIFOR *)&x,BasicType); //判断x是否是FcData数据
if(BasicType==real_s) //实数数组
{
pFCDArrayS=(FCDArrayS *)*(fcVOID *)&x;
px=(double *)pFCDArrayS->ArrayS;
for(i=0;i<pFCDArrayS->Dimension[1];i++)
{
px[i]=i; //数组元素赋值为连续整数
}
}
if(GetFor(L"b",2,NULL,nModule,bFor,Para,PareNum)) //查找全局函数b
{
if(PareNum==0) //函数有1个自变量
{
xx[0]=x; //执行脚本函数b(x)
RealCal(bFor,xx);
}
}
IsFcData(*(fcIFOR *)&x,BasicType); //判断x是否仍然是FcData数据
if(BasicType==real_s) //实数数组
{
pFCDArrayS=(FCDArrayS *)*(fcVOID *)&x;
px=(double *)pFCDArrayS->ArrayS;
for(i=0;i<pFCDArrayS->Dimension[1];i++)
{
wcout<<px[i]<<L" ";
}
}
UseForcal(0); //归还Forcal的使用权
}
wcin.get();
FreeDll(); //卸载Forcal扩展库
FreeGForcal(); //释放GForcal
}
运行结果:
1 2 3
本例子演示了如何通过GForcal的输出函数与Forcal系统交互数据。演示要点如下:
(1)通过函数SetReals向GForcal缓冲区传送数据,是一个实数数组。
(2)获取并运行了Forcal脚本中的全局函数a,该函数对传入的每一个数据元素加1。
(3)通过函数GetReals获得GForcal缓冲区中的实数数组数据。
C/C++源代码:
#include <windows.h>
#include <iostream>
#include <math.h>
#include "forcal32w.h"
#include "gforcal32w.h"
#pragma comment( lib, "GForcal32W.lib" )
using namespace std;
void main(void)
{
wchar_t str1[]=L"~a(:i,k,x)= k=FcGet(), i=0,(i<k).while{FcGet(i,&x), FcSet(i,x+1), i++};"; //存放Forcal表达式
fcVOID nModule;
void *hModule,*myFor,*Para;
fcINT err1,err2,PareNum;
double xx[3]={0,1,2};
wcout.imbue(locale("chs")); //设置输出的locale为中文
wcin.imbue(locale("chs")); //设置输入的locale为中文
InitGForcal(); //初始化GForcal
if(!UseForcal(2)) //申请使用Forcal
{
nModule=0; //由MForcal自动指定模块号
ComModule(str1,nModule,hModule,err1,err2); //将字符串源代码编译为模块
SetReals(xx,3); //向GForcal缓冲区传送数据
if(GetFor(L"a",2,NULL,nModule,myFor,Para,PareNum)) //查找全局函数a
{
if(PareNum==-1) //函数有0个自变量
{
RealCal(myFor,xx);
}
}
GetReals(xx,3); //从GForcal缓冲区获得数据
wcout<<xx[0]<<L" "<<xx[1]<<L" "<<xx[2];
UseForcal(0); //归还Forcal的使用权
}
wcin.get();
FreeGForcal(); //释放GForcal
}
运行结果:
1 2 3
任意对象都可以注册到Forcal中,参考:如何在FORCAL中添加对象、如何在FORCAL扩展库中添加对象。一般,对象有2种:
(1)用函数InsertKey注册的对象。这类对象可通过函数SearchKey获取和验证。对象标识是一个fcKEY整数,要将该标识注册为Forcal常量。
(2)通过FcData注册的对象。这类对象可参考3.4中的操作。对象标识是一个fcdTYPE整数,要将该标识注册为Forcal常量。
无论哪种对象,必须知道该对象的标识和对象的定义。对象标识应已经注册为Forcal常量,故可用函数ExMsgWithForcal获取;对象的定义由对象的设计者提供。
版权所有© Forcal程序设计 2002-2010,保留所有权利
E-mail: forcal@sina.com QQ:630715621
最近更新: <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%Y年%m月%d日" startspan -->2010年12月13日<!--webbot bot="Timestamp" i-checksum="1417" endspan -->