目 录
1、OpenForcal的输出函数
2、如何加载使用OpenForcal
3、最简单的例子
4、简单的例子
5、使用更多功能的例子
1、OpenForcal的输出函数 [目录]
1.1 初始化动态库:bool InitDll(char *pIni,char *pHlp);
pIni为初始化文件名(含文件路径),如果设为NULL,OpenForcal将自动在当前目录中搜索OpenFC.ini进行加载;任何情况下,若加载不成功,OpenForcal将按缺省值进行初始化。
pHlp为动态库说明文件名(含文件路径),如果设为NULL,OpenForcal将自动在当前目录中搜索OpenFChlp.ini进行加载。动态库说明文件的格式请参考“如何对OpenForcal进行功能扩展->3
如何编写动态库函数说明文件”。
初始化成功时返回true。
1.2 编译源程序:int ComFor(char *FcStr,char *&ErrStr,void (*outl)(long ),void (*outd)(double ),void (*outc)(_complex ),void (*myMessage)(char *));
FcStr为指向源程序字符串的指针;ErrStr返回编译信息;outl(输出整数表达式的值)、outd(输出实数表达式的值)、outc(输出复数表达式的值)、myMessage(输出字符串信息)四个函数在执行表达式时被调用,输出信息,这四个参数也可设为NULL。该函数返回值的意义如下:
ComFor=0,编译成功。
ComFor=-1,禁止编译执行表达式,表示OpenForcal要释放动态库,因此要做好退出前的清理工作。
ComFor=-2,表示资源被占用,无法对源程序进行编译,可稍后重新进行编译;
ComFor=-3,没有表达式;
ComFor=-4,内存错误;
ComFor=-5,预编译错误;
ComFor=-6,注释符号/* ... */不成对;
ComFor=-7,文件太长,需重新设置文件最大长度;
ComFor=-8,不能使用FORCAL;
ComFor=-9,表达式太长;
ComFor=-10,整数表达式不够用,需重新设置;
ComFor=-11,复数表达式不够用,需重新设置;
ComFor=-12,实数表达式不够用,需重新设置;
ComFor=-13,不能正常设置一个常量;
ComFor=-14,常量定义错误,常量名由ErrStr返回;
ComFor=-15,不能正常设置一个自动常量;
ComFor=-16,自动常量定义错误,自动常量名由ErrStr返回;
ComFor=1,不正确的运算方式;
ComFor=2,无表达式;
ComFor=3,变量说明错,等号前有非法字符;
ComFor=4,变量应放在 ( ) 内;
ComFor=5,非法变量字符(以英文字母开头的英文字母与数字的组合);
ComFor=6,变量名以英文字母开头;
ComFor=7,变量重复说明;
ComFor=8,括号不成对;
ComFor=9,在复数计算时,不能用 i
作为变量(该返回值在编译复数表达式时使用);
ComFor=10,不可识别函数名;
ComFor=11,数学表达式太长,接近32766个字符;
ComFor=12,不可识别变量;
ComFor=13,数字错误;
ComFor=14,不可识别字符、函数名、变量名或者一级函数有多个自变量;
ComFor=15,内存分配失败;
ComFor=16,二级函数错误;
ComFor=17,符号定义错误或无表达式或括号不成对;
ComFor=18,表达式中的字符串无效,即"..."不匹配;
ComFor=19,没有启用forcal的字符串处理功能;
ComFor=20,表达式中的字符串太多或表达式太长;
ComFor=21,内存分配失败;
ComFor=22,找不到字符串$"..."所表示的表达式的类型;
ComFor=23,找不到字符串#"..."所表示的表达式的序号;
ComFor=24,找不到字符串&"..."或@"..."的地址;
ComFor=25,字符串数组不够用,需重新设置;
ComFor=26,超出共享版允许的字符限制,请注册使用正式版[在正式版中无此返回值];
1.3 执行程序 int ExeFor(long Begin,long end,int mode);
Begin为开始执行的起始地址,End为结束地址,这两个地址可在OpenForcal主程序中由GetAddress[]函数获得。mode用于设置运行模式。
mode=1:执行编译表达式时设定的输出函数,且遇到另一个程序正在运行时返回代码2;
mode=2:执行编译表达式时设定的输出函数,且遇到另一个程序正在运行时不返回代码2,等待运行;
mode=3:不执行编译表达式时设定的输出函数,且遇到另一个程序正在运行时返回代码2;
mode=4:不执行编译表达式时设定的输出函数,且遇到另一个程序正在运行时不返回代码2,等待运行;
该函数返回值意义如下:
ExeFor=0,正常执行程序;
ExeFor=-1,禁止编译执行表达式,表示OpenForcal要释放动态库,因此要做好退出前的清理工作;
ExeFor=1,程序没有编译,不能运行;
ExeFor=2,另一个程序正在运行,不能同时执行,当mode=1或mode=3时返回该参数;
ExeFor=3,运行地址错误,表示Begin或End非法;
如果ExeFor以mode=3或mode=4方式运行,只能禁止编译表达式时设定的输出函数的输出,并不能禁止其他动态库中任何形式的输出,在OpenForcal的源程序中需要特别注意这一点。
1.4 释放动态库:void FreeDll(void);
1.5 自定义预编译处理程序:void PreCom(bool (*pPreCom)(char *&str));
PreCom可以将主调程序中预编译处理函数pPreCom(在主调程序中定义)的地址传送给OpenForcal,在每一次编译源程序之前,OpenForcal都将调用主调程序的预编译处理函数pPreCom对源程序进行预处理。
其中字符串指针str指向存放源程序的地址,除了不能用该指针释放该地址空间之外,可以进行其他任意的操作,包括将该指针指向另一个地址空间。
预编译没有错误时返回true。
1.6 向OpenForcal发送信息:void DllMessage(pSetMyMessage );
调用 DllMessage可以获得OpenForcal传送过来的用于向OpenForcal发送信息的函数的地址,其中pSetMyMessage的类型定义如下:
typedef void (* pMyMessage) (char *);
typedef void (* pSetMyMessage) (pMyMessage);
在主调程序中定义一个pSetMyMessage类型的函数,函数说明如下:
void GetDllMessage(pMyMessage );
pMyMessage pMyMessagep=NULL;//接受信息函数的地址;
函数定义:
void GetDllMessage(pMyMessage p) {pMyMessagep=p;}
在主调程序中可以调用DllMessage(GetDllMessage)函数将GetDllMessage的地址传送给OpenForcal。这样,在每次编译源程序之前,OpenForcal都会调用GetDllMessage()函数,将信息函数的地址(即ComFor(...)函数中的myMessage参数)传送给主调程序。因此,在主调程序中使用pMyMessagep()函数向OpenForcal发送信息,就是调用myMessage()函数发送信息。例如:
pMyMessagep("\r\n这里是预处理程序!\r\n");
1.7 定义可由OpenForcal调用的实数函数:void RegRealFun(char **ppchRealNameDll,int *piRealParaDll,double (**ppRealFunDll)(int ,double *));
RegRealFun用于向OpenForcal注册实数函数。字符串数组ppchRealNameDll存放函数名,整数数组piRealParaDll存放自变量个数,函数指针数组ppRealFunDll存放函数地址。
实数函数均具有以下形式;
double rfc_add(int ,double *);
double rfc_sub(int ,double *);
double rfc_nstr(int ,double *);
以下定义中ppchRealNameDll、piRealParaDll、ppRealFunDll的参数要对应。
char *ppchRealNameDll[]={"add","sub","nstr",""};
//定义在OpenForcal源程序中使用的函数名;
int piRealParaDll[]={1,1,1}; //-2表示有不确定的多个自变量,-1表示有0个自变量,0表示有1个自变量,1表示有2个自变量;
double (*ppRealFunDll[])(int ,double *)={rfc_add,rfc_sub,rfc_nstr};
//函数指针数组;
请参考FORCAL使用说明1.6中的11、“设置可由FORCAL调用的外部函数”。
1.8 定义可由OpenForcal调用的整数函数:void RegIntFun(char **,int *,long (**)(int ,long *));
RegIntFun用于向OpenForcal注册整数函数。该部分的说明与“可由OpenForcal调用的实数函数”类似,请参考1.7中的说明。
1.9 定义可由OpenForcal调用的复数函数:void RegComplexFun(char **,int *,_complex (**)(int ,_complex *));
RegComplexFun用于向OpenForcal注册复数函数。该部分的说明与“可由OpenForcal调用的实数函数”类似,请参考1.7中的说明。
1.10 使用字符串:void GetFcStr(char **&ppchFcStr,long *&plFcStrMax,long &StrsMax);
ppchFcStr为字符串数组指针;plFcStrMax指向一个存放字符串大小的长整形数组,该数组与ppchFcStr相对应,指出了ppchFcStr中各个字符串的大小;StrsMax为字符串数组ppchFcStr的大小。
请参考FORCAL使用说明中的字符数据处理。
使用FORCAL字符串需要注意以下问题:
(1)、使用字符串之前先检查地址是否有效,字符串地址用一个整数表示,0<=地址<StrsMax;
(2)、如果释放了一个字符串,把该指针置为NULL,同时将串的大小置为0。
1.11
使用Forcal实数表达式:void GetRealFor(double (*&pRCALS)(int ),int (*&pFCERRNUM)(void),void (*&pSETFCERR)(int ,char *),bool *&fortrue,double **&allin,int *&forpara,int &rfor_max); pRCALS:计算实数表达式的值;
pFCERRNUM:获得Forcal中实数表达式运行错误代码,0表示没有错误;
pSETFCERR:设置外部函数运行错误,字符串指针指出出错函数名;
fortrue:存放各个实数表达式的编译状态,表达式编译通过时设为true;
allin:allin指向存放各实数表达式自变量的指针数组;
forpara:存放各个实数表达式的自变量个数;
rfor_max:最多可用的实数表达式数目。
请参考FORCAL使用说明1.6中相关函数的说明。
使用FORCAL表达式进行计算需要注意以下问题:
(1)、检查rfor_max是否大于0,rfor_max>0时可以使用表达式,在OpenForcal中,rfor_max总是大于0,因此也可以不检查此项;
(2)、检查表达式是否存在,0<=表达式序号<rfor_max;
(3)、检查表达式编译是否通过,fortrue[表达式序号]=true时可以使用;
(4)、检查表达式参数个数是否匹配;
(5)、用pfcerrnum()函数可以获得FORCAL运行错误,出现错误时不再进行计算;
(6)、如果pfcerrnum()==0,可以用psetfcerr()函数向FORCAL报告错误;
(7)、一般情况下,FORCAL函数不允许递归。终止递归的方法是设置一个静态变量,用以记录该函数被调用的次数,当被调用的次数大于setstackmax(n)函数的设定值时,即认为出现了递归。当然,这种检测递归的方法同时也限制了该函数被嵌套调用的次数。
1.12 使用Forcal整数表达式:void GetIntFor(pICALS &,pIFCERRNUM &,pISETFCERR &,bool *&,long **&,int *&,int &);
该部分的说明与“使用Forcal实数表达式”类似,请参考1.11中的说明。
1.13 使用Forcal复数表达式:void GetComplexFor(pCCALS &,pCFCERRNUM &,pCSETFCERR &,bool *&,_complex **&,int *&,int &);
该部分的说明与“使用Forcal实数表达式”类似,请参考1.11中的说明。
1.14 使用FORCAL实数数组:void GetFcDoubleArray(pGETFCDOUBLEARRAYS &pGETFCDOUBLEARRAYSp);
由GetFcDoubleArray可以获得一个函数的地址pGETFCDOUBLEARRAYSp,由该函数可以获得FORCAL实数数组的地址信息。该函数的类型定义如下:
typedef double **(* pGETFCDOUBLEARRAYS) (long &,long
*&);
pGETFCDOUBLEARRAYS pGETFCDOUBLEARRAYSp;
若定义:
double **ppfcdoublearray; //多维存储数组doublearray的指针;
long fcdoublearrayMax; //多维存储数组doublearray的大小;
long *pfcdoublearrayMax; //多维存储数组doublearray中各维数组长度的整数组的指针;
则由ppfcdoublearray=pGETFCDOUBLEARRAYSp(fcdoublearrayMax,pfcdoublearrayMax);获得FORCAL实数数组的地址信息。
请参考FORCAL使用说明1.6中相关函数的说明。
使用FORCAL数组需要注意以下问题:
(1)、检查ppfcdoublearray是否为真,ppfcdoublearray为真时可以使用数组;
(2)、检查数组是否存在,0<=数组序号fcdoublearrayMax<rfor_max;
(3)、使用数组不要越界。
1.15 使用FORCAL复数数组:void GetFcComplexArray(pCGETFCCOMPLEXARRAYS &);
该部分的说明与“使用FORCAL实数数组”类似,请参考1.14中的说明。
1.16 使用FORCAL整数数组:void GetFcLongArray(pIGETFCLONGARRAYS &);
该部分的说明与“使用FORCAL实数数组”类似,请参考1.14中的说明。
1.17 获得OpenForcal的设置:void GetOpenFcSet(long &textmax,int &intmax,int &realmax,int &complexmax,long &strmax,char *&pch,char *&pdllfile);
textmax:源程序最大长度;
intmax:整数表达式最多个数;
realmax:实数表达式最多个数;
complexmax:复数表达式最多个数;
strmax:最多可用的字符串个数;
pch:扩展动态库文件,多个文件之间用空格、Tab键或者换行符分隔,注意以字符*开头的文件被忽略,在<...>中的文件被忽略(字符“<”应在某个文件名的开头);
pdllfile
:扩展动态库说明文件,多个文件之间用空格、Tab键或者换行符分隔,注意以字符*开头的文件被忽略,在<...>中的文件被忽略(字符“<”应在某个文件名的开头)。
1.18 设置OpenForcal:int SetOpenFcSet(long textmax,int intmax,int realmax,int complexmax,long strmax,char *pch);
textmax:源程序最大长度;
intmax:整数表达式最多个数;
realmax:实数表达式最多个数;
complexmax:复数表达式最多个数;
strmax:最多可用的字符串个数;
pch:扩展动态库文件,多个文件之间用空格、Tab键或者换行符分隔,注意以字符*开头的文件被忽略,在<...>中的文件被忽略(字符“<”应在某个文件名的开头)。
函数返回值的意义如下:
0、设置成功;
1、未注册用户,没有设置文件最大长度,其他项设置成功。
2、内存分配错误。
3、FORCAL设置错误;
4、加载扩展动态库时出现致命错误。
1.19 加载动态库说明文件:bool LoadDllFunFile(char *pch);
若加载成功返回true,否则返回false。
pch:扩展动态库说明文件,多个文件之间用空格、Tab键或者换行符分隔,注意以字符*开头的文件被忽略,在<...>中的文件被忽略(字符“<”应在某个文件名的开头)。
在该函数执行结束之前,应禁止通过pDllFunFile进行任何操作(无论是在主调程序还是在OpenForcal的扩展动态库中),pDllFunFile是通过pDllFunFile=GetDllFunFile()获得的指向动态库说明文件地址的指针。
1.20 使用Openforcal的临界区:void OfcCriticalSection(int inout);
inout=1,进入临界区,但并不禁止源代码的编译和执行,动态库的说明信息,只许读,不许写;
inout=1,进入临界区,同时禁止源代码的编译和执行,允许读写动态库说明信息;
inout=0,离开临界区。
注意:不要在临界区中使用OpenForcal扩展动态库的任何一个输出函数。
通常,使用动态库的说明信息时需要在临界区中进行。例如:
OfcCriticalSection(1);//进入临界区;
//...访问动态库的说明信息...
OfcCriticalSection(0);//离开临界区;
1.21 得到动态库的说明信息:DllFunFile *GetDllFunFile();
类DllFunFile的类型定义如下:
class DllFunChar
{public:
char *pstrname,*pstr;
DllFunChar *headDllFunChar,*endDllFunChar;
DllFunChar();
DllFunChar(DllFunChar *);
~DllFunChar();
bool setDllFunCharName(char *);
bool setDllFunChar(char *);
};
class DllFunFile
{public:
char *DllFunFilename;
DllFunChar *pDllFunChar,head_DllFunChar;
DllFunFile *headDllFunFile,*endDllFunFile;
DllFunFile();
DllFunFile(DllFunFile *);
~DllFunFile();
bool setDllFunFilename(char *);
};
该类中数据成员的说明请参考“如何对OpenForcal进行功能扩展”中“3
如何编写动态库函数说明文件 ”。
1.22 获得或设置主程序初始化信息:char *ExternIniText(char *pch);
OpenForcal可以为主程序保存初始化信息。使用方法如下:
ExternIniText(NULL):获得初始化信息,该函数通常在程序开始时调用。
ExternIniText(pch):保存初始化信息,pch为信息字符串,该函数通常在程序结束前调用。
该函数返回当前初始化信息字符串;若该函数返回NULL,则发生内存错误。
2 如何加载使用OpenForcal [目录]
2.1 OpenForcal的初始化及加载
首先,必须有forcal.dll的支持,OpenForcal才能进行工作,以后我们总是假定能正常的加载使用forcal.dll,把forcal.dll放到windows的搜索路径内或者把forcal.dll和OpenForcal放在一起即可做到这一点。
OpenForcal提供了带参数的的初始化函数bool InitDll(char
*pIni,char *pHlp),因此,我们可以将加载OpenForcal的程序和OpenForcal.dll分别存放在硬盘的不同位置,这不但不会影响程序的性能,而且效率更高。无论使用OpenForcal的程序有多少,硬盘上可以只保留一个OpenForcal.dll文件,节省了磁盘空间;同时,不同的程序使用保存在不同位置的初始化文件对OpenForcal进行初始化,相互之间没有任何影响。
一般要将OpenForcal.dll放到windows的搜索路径内。
要使用显式方式链接动态库OpenForcal.dll。
2.2 函数的使用次序
(1)如果要向OpenForcal注册可由Forcal调用的外部函数,必须在初始化之前进行,即RegRealFun()、RegIntFun()、RegComplexFun()三个函数要在InitDll()之前使用。
(2)用InitDll()函数初始化OpenForcal。通常,在调用InitDll()函数之前,不要调用下面除FreeDll()之外的任何函数。
(3)可以调用GetRealFor()、GetIntFor()、GetComplexFor()三个函数以便使用Forcal的实数、整数和复数表达式;可以调用GetFcStr()以便使用Forcal字符串。
(4)可以调用GetFcDoubleArray()、GetFcComplexArray()、GetFcLongArray()以便使用Forcal的实数、复数和整数数组;可以调用PreCom()设置主调程序的预处理函数;可以调用DllMessage()函数以便向OpenForcal发送信息。
(5)用ComFor()编译源程序之后,可以多次调用ExeFor()进行计算。(1~4)中的函数只能在使用ComFor()和ExeFor()之前调用。
(6)可以调用GetOpenFcSet()获得OpenForcal的当前设置。
(7)可以调用GetDllFunFile()获取动态库的说明信息。
(8)可以调用SetOpenFcSet()函数对OpenForcal重新进行设置,重新设置后,必须重新调用(3)中的函数(如果这些函数在以前使用过)。重新设置后,将丢失以前的编译结果。
(9)可以调用LoadDllFunFile()函数重新加载动态库说明文件。
(10)可以调用ExternIniText()函数获得或设置主程序初始化信息。
(11)只要使用了前面的任何一个函数,程序退出时,都要用FreeDll()释放OpenForcal。
2.3 最简单的使用方式
(1)用InitDll函数初始化动态库;
(2)用ComFor函数编译源程序;
(3)用ExeFor函数执行程序;
(4)用FreeDll函数释放动态库。
2.4 使用OpenForcal.dll的其他功能
请参考“1、OpenForcal的输出函数”中其他函数的说明。
#include <windows.h>
#include <iostream.h>
HINSTANCE OpenForcalDll;//存放动态库的地址;
//得到初始化动态库函数的地址;
typedef bool (* pInitDll)(char *,char *);
pInitDll pInitDllp;
//得到释放动态库函数的地址;
typedef void (* pFreeDll)(void);
pFreeDll pFreeDllp;
void main()
{OpenForcalDll=LoadLibrary("OpenForcal.dll");
if(OpenForcalDll)
{pInitDllp=(pInitDll) GetProcAddress(OpenForcalDll,"InitDll");
pInitDllp(NULL,NULL); //初始化动态库;
pFreeDllp=(pFreeDll) GetProcAddress(OpenForcalDll,"FreeDll");
}
else
{MessageBox(NULL,"找不到动态库OpenForcal.dll,请将OpenForcal.dll放到Windows的搜索路径内!","SimpleOpenFC",MB_OK);}
cout<<"最简单的使用OpenForcal的例子。\r\n需要扩展动态库FcWin.dll的支持,在FcWin窗口进行操作。\r\n按回车键Enter结束程序 !";
cin.get();
if(OpenForcalDll) {pFreeDllp(); FreeLibrary(OpenForcalDll);} //释放动态库;
}
用Visual C++6.0向导建立一个MFC
AppWizard(exe)工程,工程名为SimpleOpenFC,除应用程序类型选择Dialog
based外,其余使用默认选项。工程建好后,选择菜单Build->Set
Active Configuration中Wiin32 Release选项进行编译。
我们在对话框窗口上放置两个文本编辑框和一个“计算”按钮。两个文本编辑框中其中一个编辑框的ID改为IDC_text,添加一个CEdit控件m_text,用于接收源程序文件;另一个编辑框的ID改为IDC_out,添加一个CEdit控件m_out,用于输出计算结果。“计算”按钮的ID改为IDC_cal,为单击该按钮添加一个函数。添加一个程序退出时被自动执行的函数DestroyWindow()。
进行完以上工作,打开文件SimpleOpenFCDlg.cpp,我们将在该文件中添加有关内容。
首先在文件开头添加下面一行
,以便使我们能够使用数学函数:
#include "math.h" //使用数学函数;
接下来在文件说明部分添加如下全局常量定义和函数说明:
HINSTANCE OpenForcalDll;//存放动态库的地址;
//得到初始化动态库函数的地址;
typedef bool (* pInitDll)(char *,char *);
pInitDll pInitDllp;
//得到释放动态库函数的地址;
typedef void (* pFreeDll)(void);
pFreeDll pFreeDllp;
//得到编译函数的地址;
typedef void (* pCOMPLEXfun) (_complex );
typedef void (* pDOUBLEfun) (double );
typedef void (* pLONGfun) (long );
typedef void (* pDllMessage) (char *);
void outl(long);
void outd(double);
void outc(_complex);
void DllMessage(char *);
typedef int (* pComFor) (char *,char *&,pLONGfun ,pDOUBLEfun
,pCOMPLEXfun ,pDllMessage);
pComFor pComForp;
//得到计算函数的地址;
typedef int (* pExeFor) (long ,long ,int);
pExeFor pExeForp;
//保存输出窗口的地址;
CEdit *pout;
下面添加函数实现。
找到CSimpleOpenFCDlg::OnInitDialog()函数,添加如下初始化内容:
// TODO: Add extra initialization here
OpenForcalDll=NULL;
OpenForcalDll=LoadLibrary("OpenForcal.dll");
if(OpenForcalDll)
{pComForp=(pComFor) GetProcAddress(OpenForcalDll,"ComFor");
pExeForp=(pExeFor)
GetProcAddress(OpenForcalDll,"ExeFor");
pInitDllp=(pInitDll)
GetProcAddress(OpenForcalDll,"InitDll");
pInitDllp(NULL,NULL); //初始化动态库;
pFreeDllp=(pFreeDll)
GetProcAddress(OpenForcalDll,"FreeDll");
}
else
{AfxMessageBox("找不到动态库OpenForcal.dll,请将OpenForcal.dll放到Windows的搜索路径内!",MB_OK,0);}
pout=&m_out;//保存输出窗口的地址;
找到CSimpleOpenFCDlg::Oncal()函数,修改该函数的内容如下,当单击“计算”按钮时,将执行该函数:
void CSimpleOpenFCDlg::Oncal()
{
// TODO: Add your control notification handler code here
CString textstr;
int n;
char *err_str="",ch[32];
m_text.GetWindowText(textstr);
if(OpenForcalDll)
{n=pComForp((char *)(LPCTSTR)textstr,err_str,outl,outd,outc,DllMessage);
if(n)
{m_out.ReplaceSel(err_str);
m_out.ReplaceSel("\r\n编译错误代码:");
m_out.ReplaceSel(itoa(n,ch,10));
}
pExeForp(0,-1,2);
}
}
找到CSimpleOpenFCDlg::DestroyWindow()函数,修改该函数的内容如下,当程序退出时,将执行该函数,以便能够释放动态库:
BOOL CSimpleOpenFCDlg::DestroyWindow()
{
// TODO: Add your specialized code here and/or call the base class
if(OpenForcalDll)
{pFreeDllp();
FreeLibrary(OpenForcalDll);
}
return CDialog::DestroyWindow();
}
最后,在文件的末尾添加如下函数实现:
void outl(long ll)
{char ch[32];
pout->ReplaceSel("i:");
pout->ReplaceSel(ltoa(ll,ch,10));
pout->ReplaceSel("\r\n");
}
void outd(double dd)
{char ch[32];
pout->ReplaceSel(gcvt(dd,16,ch));
pout->ReplaceSel("\r\n");
}
void outc(_complex cc)
{char ch[32];
pout->ReplaceSel("c:");
pout->ReplaceSel(gcvt(cc.x,16,ch));
if(cc.y>=0.0) pout->ReplaceSel("+");
pout->ReplaceSel(gcvt(cc.y,16,ch));
pout->ReplaceSel("i\r\n");
}
void DllMessage(char *ch) {pout->ReplaceSel(ch); pout->ReplaceSel("\r\n");}
好了,文件修改完毕,重新编译运行即可。
为了使程序能够正常运行,需要将OpenForcal.dll和Forcal.dll两个文件放到windows的搜索路径内。
请参考OpenFCtest工程,这是一个使用OpenForcal更多功能的例子。