欢迎访问 Forcal程序设计

FORCAL扩展动态库

往Forcal中添加常量、函数或其他任意类型的数据是非常方便的。为了便于函数和数据共享，常将函数和数据封装到动态库中，以动态库的形式向Forcal添加，这种动态库称Forcal扩展动态库。Forcal扩展动态库只需要一个输出函数：

//Forcal扩展动态库唯一的输出函数；
//hFC：Forcal32W.dll的句柄；bInit=true：初始化动态库，bInit=false：释放动态库；
//me：指向任意数据的指针，可用于验证用户能否使用该库，为了方便验证，约定该指针指向一个wchar_t类型的字符串。
//bInit=true时，返回值ForcalDll=0：初始化失败；ForcalDll=1：初始化成功；返回值ForcalDll=2：初始化成功，仅注册一些常量，初始化完成后可卸载该库。
//bInit=false时，返回值ForcalDll=0：释放失败；ForcalDll=1：释放成功；
extern "C" int _stdcall FcDll32W(HINSTANCE hFC,bool bInit,void *me)
{
.
.
.
if(bInit) //初始化动态库
{
.
.
.
return 1;
}
else //释放动态库
{
.
.
.
return 1;
}
}

可以看出，虽然Forcal扩展动态库只有一个输出函数，但该函数接受了主调程序加载的Forcal32W.dll的句柄，因而可以完成任意复杂的功能。为了应用程序的安全性，在Forcal扩展动态库中禁止使用InitForcal(初始化FORCAL)和FreeForcal(释放FORCAL)这两个函数。

设计商业性Forcal扩展动态库时，在初始化过程中要验证me，看宿主程序提供的字符串形式的注册码是否符合要求，若符合要求，商业库可提供全部功能，否则仅提供部分功能或禁止使用该库。

如果在动态库中启动了另一线程，要注意多线程程序中使用Forcal函数的原则，即：除了GetRunErr()、TestRunErr()和SetRunErr()三个函数外，其余的函数只能在单线程中使用（不允许两个及两个以上的线程同时运行这些函数）。为此，约定用pUseForcal=SearchKey("UseForcal",FC_PrivateKey_User); 获得一个函数指针进行多线程之间互斥使用Forcal的通讯，该函数可在主程序或Forcal扩展动态库中定义，函数说明如下：

//（1）iUse=1时，表示要申请使用Forcal，若函数返回值 UseForcal=0：申请成功；UseForcal=1：申请不成功，
//其他线程正在使用Forcal，稍后再进行申请；UseForcal=-1：申请不成功，表示应用程序要释放Forcal，
//因此要做好退出前的准备工作。
//（2）iUse=2时，表示要申请使用Forcal，如果其他线程正在使用Forcal，函数不返回，进行等待，直至申请成功。
//若函数返回值 UseForcal=0：申请成功；UseForcal=1：申请不成功，线程本身正在使用Forcal，不能重复进行申请；
//UseForcal=-1：申请不成功，表示应用程序要释放Forcal，因此要做好退出前的准备工作。
//（3）iUse=0时，表示要归还Forcal的使用权，函数返回值无意义。
//（4）iUse=3时，设置安全标志，表示Forcal运行正常，函数返回值无意义。 一般在二级函数中设置该标志，当该函
//数在较长时间内运行时，可用此标志通知Forcal，此时的运行是正常的，没有陷入无限循环等情况。
//（5）iUse=4时，取消安全标志，表示Forcal运行处于不可控制阶段（有陷入无限循环的可能），函数返回值无意义。
//（6）iUse=5时，查询安全标志，UseForcal=0：运行正常；UseForcal=1：运行情况无法预测（有陷入无限循环的可
//能），这是Forcal运行的一般情况。
//注意1：Forcal是极为重要而有限的资源，用完后要及时归还。
//注意2：UseForcal(1)（或者UseForcal(2)）和UseForcal(0)必须成对使用。注意不能在二级函数中使用该功能，
//因为二级函数本身就是在Forcal工作区中运行的。
//注意3：UseForcal(3)和 UseForcal(4)也要成对使用，且一般在二级函数中使用该功能。
extern "C" int _stdcall UseForcal(int iUse);

在主调程序或任一个Forcal扩展动态库中均可以设置一个函数void _stdcall FcMessage(wchar_t *);。然后将该函数的地址用InsertKey("FcMessage",9,FC_Key_User,FcMessage,NULL,v)传送给Forcal。约定所有Forcal扩展动态库都使用该函数发送信息。任一线程均可根据需要设置该函数。

在设计Forcal扩展动态库时，要采用二级函数命名空间方式（例如："Fun2Space::FunName"）输出函数，以尽量避免函数重名。

在设计Forcal扩展动态库时，要遵循谁注册函数和数据谁释放的原则。

在加载和卸载Forcal扩展动态库时，要遵循先进后出的原则，即先加载的后进行卸载。

可以用C/C++、delphi、FORTRAN等任一种高级语言设计Forcal扩展动态库。

以下是目前的几个Forcal动态库列表，这些库可以通过程序“ForcalTest.exe”、“ForcalDemo.exe”或“MForcalDemo.exe”进行演示：

类别及说明 | 动态库 | 用途
基础库：完成最重要的功能或包含最重要的库函数，可作为构建其他动态库的基础 | FcData32W | Forcal数据扩展动态库。支持简单的到任意复杂的数据类型，基本操作对象是FcData数据指针。
MForcal32W | Forcal模块化编译运行动态库。
QuitFc32W | 退出Forcal运行时的无限循环。在任意可接受输入的窗口，按 Ctrl+Alt+Q(q) 键可以退出Forcal运行时的无限循环。
标准库：比较规范，经过优化的实用动态库 | FcDataEx32W | Forcal数据扩展动态库。在FcData32W的基础上，直接操作复杂的FcData数据类型。
FcIO32W | Forcal标准输入输出动态库。
FcString32W | Forcal字符串操作动态库。
FcSystem32W | Forcal系统函数库，主要是Forcal系统或操作系统相关的函数。
OpenFcGl32W | 基于OpenGL的进行图形绘制的动态库。
FcWin32W | 是一个Windows窗口库，包含一些实用窗口函数。例如：用户可在控件窗口中自定义多个控件。
XSLSF32W | Forcal数值计算扩展动态库，包含大量数值算法。所包含的算法都是行之有效的，基本可以满足解决工程中各种实际问题的需要。
例子动态库：帮助用户学习用的动态库，实用性差。
FcConst | 向Forcal中添加常量，添加完常量即可卸载该库。
Example | 向Forcal注册函数。

版权所有© Forcal程序设计 2002-2010，保留所有权利
E-mail: forcal@sina.com QQ：630715621
最近更新: 2010年09月27日