欢迎访问 Lu程序设计

C/C++使用MLu简化Lu脚本系统的使用

1 说明

    要演示本文的例子,你必须下载Lu64脚本系统。本文的例子需要lu64.dll、mlu64.dll、lu64.lib、mlu64.lib、C++格式的头文件lu64.h,相信你会找到并正确使用这几个文件。

    用C/C++编译器创建一个控制台应用程序,复制本文的例子代码直接编译运行即可。

2 关于Lu模块化边缘运行库MLu

    MLu是程序和Lu核心库之间的一个接口库,MLu会自动加载Lu核心库和动态加载多个Lu扩展库,简化了Lu系统的使用;MLu可对Lu源程序进行模块化编译,能够编译运行具有固定格式的源程序(字符串表达式),源程序中可以使用C++风格的注释。此外,MLu还提供了多个线程互斥地访问Lu资源的功能;提供了Lu运行监视器,以退出耗时较长的程序;提供在脚本中动态编译函数的功能;提供错误处理函数,实现错误(异常)处理的恢复模型等等。详细参考MLu使用说明,同时参考软件包lu2code.zip中的MLu的源代码。

3 代码

代码1:使用MLu对源代码进行模块化编译,C/C++程序使用核心库函数GetFor查找全局脚本函数进行计算

#include <windows.h>
#include <iostream>
#include "lu64.h"			//Lu头文件
#pragma comment( lib, "lu64.lib" )
#pragma comment( lib, "mlu64.lib" )
using namespace std;
void main(void)
{
	void *hModule;		//模块句柄
	luINT ErrBegin,ErrEnd;	//表达式编译出错的初始位置和结束位置
	int i;			//错误代码
	void *hFor;		//表达式句柄
	luVOID nModule=0;		//表达式所在模块
	LuData *pPara;		//存放输入自变量的数组指针
	luINT nPara;		//存放表达式的自变量个数
	LuData Val;		//存放表达式的值
	wchar_t ForStr[]=L"f(x)=x+1; :::ff(x,y)=f(x)+y;";	//Lu模块化源程序,函数f为私有函数,函数ff为全局函数
	if(!InitMLu()) return;	//初始化MLu
	if(!UseLu(2))		//申请使用Lu资源
	{
		i=ComModule(ForStr,nModule,hModule,ErrBegin,ErrEnd);	//编译Lu源程序
		if(i)
		{
			cout<<"Lu源程序有错误!错误代码:"<<i<<endl;
		}
		else
		{
			if(GetFor(L"ff",1,NULL,nModule,hFor,pPara,nPara))	//查找全局函数ff
			{
				for(i=0;i<=nPara;i++)	//表达式自变量赋值,均赋值为1
				{
					pPara[i].BType=luStaData_int64; pPara[i].VType=luStaData_int64; pPara[i].x=1;
				}
				Val=LuCal(hFor,pPara);	//计算表达式的值
				cout<<Val.x<<endl;
			}
			else
			{
				cout<<"找不到指定的函数!"<<endl;
			}
		}
		UseLu(0);		//归还Lu的使用权
	}
	FreeMLu();		//释放MLu
}

运行结果:

3

代码2:通过MLu加载Lu扩展库 LuSystem64.dll 和 LuMath64.dll

#include <windows.h>
#include <iostream>
#include "lu64.h"			//Lu头文件

#pragma comment( lib, "lu64.lib" )
#pragma comment( lib, "mlu64.lib" )

using namespace std;

void _stdcall LuMessage(wchar_t *pch) //输出动态库信息,该函数注册到Lu,由Lu二级函数调用
{
	wcout << pch;
}

void main(void)
{
	void *hModule,*hErrModule;		//模块句柄
	luINT ErrBegin,ErrEnd,err1,err2;	//表达式编译出错的初始位置和结束位置
	int i;			//错误代码
	luVOID nModule=0;		//表达式所在模块
	void *NowKey;		//返回已存在的键值
	wchar_t ForStr[]=L"!!!using(\"sys\",\"math\"); main(:a)= a=new[class, #人, public : #姓名, private : #性别, #年龄], o[a, matrix[3,2].rand()], while[1,1];";

	wcout.imbue(locale("chs"));	//设置输出的locale为中文

	if(!InitMLu()) return;	//初始化MLu

	InsertKey((char *)&nModule,sizeof(luVOID),luPubKey_User,LuMessage,NULL,NULL,1,NowKey);//使Lu运行时可输出函数信息

	LoadDll(L"\"LuSystem64.dll\",\"LuMath64.dll\"");	//加载Lu扩展动态库

	if(!UseLu(2))		//申请使用Lu资源
	{
		i=ComModule(ForStr,nModule,hModule,ErrBegin,ErrEnd);	//编译Lu源程序
		if(i)
		{
			cout<<"Lu源程序有错误!错误代码:"<<i<<endl;
		}
		else
		{
			ExeModule(hModule,NULL,hErrModule,err1,err2);	//执行模块
		}
		UseLu(0);		//归还Lu的使用权
	}

	FreeDll();		//释放Lu扩展动态库

	FreeMLu();		//释放MLu
}

运行结果(运行几秒钟后会弹出一个监控窗口,按提示中断Lu运行):

class{#人 :
private:
  #性别, #年龄,
method:

public:
  #姓名,
method:
  #__init__ : 0, #__del__ : 0
}


       0.211319   4.91638e-002
       0.144638       0.153259
       0.852615       0.630646


Lu表达式运行错误!
其他运行错误!
错误描述:MLu:用户中断了Lu运行。  错误代码:0

4 函数说明

    本例用到了核心库Lu的3个输出函数:获得表达式信息函数GetFor计算表达式的函数LuCal、插入键值函数InsertKey;从这里查看这些函数的说明:Lu编程指南。 本例用到了模块化编译运行库MLu的7个输出函数:初始化MLu函数InitMLu、释放MLu函数FreeMLu、申请进入或退出Lu工作区函数UseLu、 编译源程序ComModule、执行模块函数ExeModule、加载Lu扩展动态库函数LoadDll、释放Lu扩展动态库函数FreeDll;从这里查看这些函数的说明:MLu使用说明

5 难点分析

    代码1演示了使用MLu对源代码进行模块化编译后,C/C++程序可使用核心库函数GetFor查找全局脚本函数进行计算,但无法获得模块中的私有函数。

    代码2演示了如何通过MLu加载Lu扩展库 LuSystem64.dll 和 LuMath64.dll,脚本程序输出了一个类(class)的结构和一个用随机数初始化的3×2矩阵 ,并给出了运行错误信息;类(class)是在扩展库LuSystem中定义的,而矩阵是在扩展库LuMath中定义的 ,错误信息是由于用户中断了Lu的运行(注意代码中字符串表达式ForStr的最后有一个无限循环while[1,1],必须由用户中断)。

6 其他

    你可能注意到了,我的联系方式就在下面,如有不明之处或有什么建议,可随时与我进行联系。


版权所有© Lu程序设计 2002-2021,保留所有权利
E-mail: forcal@sina.com
  QQ:630715621
最近更新: 2021年05月23日