欢迎访问 Lu程序设计
使用C/C++设计多线程程序监控Lu脚本运行
1 说明
要演示本文的例子,你必须下载Lu64脚本系统。本文的例子需要lu64.dll、lu64.lib、C++格式的头文件lu64.h,相信你会找到并正确使用这几个文件。
用C/C++编译器创建一个控制台应用程序,复制本文的例子代码直接编译运行即可。
2 关于Lu无限循环的退出
在Lu循环体(while或者until)中,必须有退出循环体的语句,否则将产生无限循环。例如 while[1,1] 就是一个无限循环。要想退出无限循环,必须设计成多线程程序,其中有一个线程专门用于监控Lu的运行,可以使用函数SetRunErr退出Lu无限循环,详细参考Lu编程指南。
3 代码
#include <windows.h> #include <iostream> #include "lu64.h" #pragma comment( lib, "lu64.lib" ) using namespace std; DWORD idThread,lpExitcode; HANDLE handleExitFc=NULL; int ExitLu(void) { MessageBox(NULL,L"强行退出Lu运行!",L"退出Lu!!!",32); SetRunErr(6,L"用户强行退出Lu!",1,0,0); return 0; } void main(void) { void *hFor; //表达式句柄 luINT nPara; //存放表达式的自变量个数 LuData *pPara; //存放输入自变量的数组指针 luINT ErrBegin,ErrEnd; //表达式编译出错的初始位置和结束位置 int ErrCode; //错误代码 int ErrType,FunCode; //返回运行错误或警告的类型,返回函数错误代码。 wchar_t *FunName; //返回出错函数名,或者运行错误说明。 void *ForHandle; //回出错表达式的句柄,该句柄即编译表达式时获得的句柄 void *Msg1,*Msg2; //与Lu交换信息用 wchar_t divbyzeroStr[]=L"1/0"; //字符串表达式,编译时运行错误 wchar_t recursionStr[]=L"a()=a()"; //字符串表达式,无穷递归调用 wchar_t whileStr[]=L"while[1,1]"; //字符串表达式,无限循环 wcout.imbue(locale("chs")); //设置输出中文 if(!InitLu()) return; //初始化Lu ErrCode=LuCom(divbyzeroStr,0,0,0,hFor,nPara,pPara,ErrBegin,ErrEnd); if(ErrCode) { wcout << L"表达式编译时出错!错误代码:" << ErrCode << endl; //检查Lu编译时运行错误 GetRunErr(ErrType,FunName,FunCode,ForHandle); if(ErrType) { wcout << L"Lu运行错误,错误类型:" << ErrType << L" 函数名: " << FunName << L" 错误代码:" << FunCode << endl; if(ForHandle) { FunName=(wchar_t *)ExMsgWithLu(2,ForHandle,Msg1,Msg2); wcout << L"表达式名称:" << FunName << L" 所在模块:" << *(luVOID *)Msg1 << endl; } } } if(0==LuCom(recursionStr,0,0,0,hFor,nPara,pPara,ErrBegin,ErrEnd)) { LuCal(hFor,pPara); //执行表达式 //检查Lu运行错误 GetRunErr(ErrType,FunName,FunCode,ForHandle); if(ErrType) { wcout << endl << L"Lu运行错误,错误类型:" << ErrType << L" 函数名: " << FunName << L" 错误代码:" << FunCode << endl; if(ForHandle) { FunName=(wchar_t *)ExMsgWithLu(2,ForHandle,Msg1,Msg2); wcout << L"表达式名称:" << FunName << L" 所在模块:" << *(luVOID *)Msg1 << endl; } } } //创建一个线程,监控Lu运行 handleExitFc=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ExitLu,NULL,0,&idThread); if(0==LuCom(whileStr,0,0,0,hFor,nPara,pPara,ErrBegin,ErrEnd)) { LuCal(hFor,pPara); //执行表达式 //检查Lu运行错误 GetRunErr(ErrType,FunName,FunCode,ForHandle); if(ErrType) { wcout << endl << L"Lu运行错误,错误类型:" << ErrType << L" 函数名: " << FunName << L" 错误代码:" << FunCode << endl; if(ForHandle) { FunName=(wchar_t *)ExMsgWithLu(2,ForHandle,Msg1,Msg2); wcout << L"表达式名称:" << FunName << L" 所在模块:" << *(luVOID *)Msg1 << endl; } } } FreeLu(); //释放Lu }
运行结果:
表达式编译时出错!错误代码:36
Lu运行错误,错误类型:1 函数名: Integer division by zero 错误代码:1
Lu运行错误,错误类型:1 函数名: StackOverFlow 错误代码:1
表达式名称:a 所在模块:0
Lu运行错误,错误类型:6 函数名: 用户强行退出Lu! 错误代码:1
4 函数说明
本例用到了Lu的7个输出函数:初始化Lu的函数InitLu,释放Lu的函数FreeLu,编译表达式的函数LuCom、 计算表达式的函数LuCal、设置运行错误函数SetRunErr、 获得运行错误函数GetRunErr、与Lu交换信息函数ExMsgWithLu。从这里查看这些函数的说明:Lu编程指南。
5 难点分析
Lu在编译字符串表达式时,对常量表达式(例如 1/2)会进行计算,因而有可能返回运行错误,编译错误代码36表示出现了运行错误,此时应检查并报告运行错误。
Lu在计算表达式时,极有可能出现运行错误,故应对运行错误进行检查。如果运行多个表达式,不必在每个表达式运行后进行检查,可在最后检查运行错误。
6 其他
你可能注意到了,我的联系方式就在下面,如有不明之处或有什么建议,可随时与我进行联系。
版权所有© Lu程序设计
2002-2021,保留所有权利
E-mail: forcal@sina.com
QQ:630715621
最近更新:
2021年05月23日