欢迎访问 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日