欢迎访问 Lu程序设计

C/C++操作Lu脚本变量

1 说明

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

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

2 Lu脚本变量

    Lu脚本函数(表达式)中可以定义和使用五种变量:自变量、动态变量、静态变量、模块变量和全局变量。自变量、动态变量和静态变量只能被定义该变量的表达式所访问;模块变量可被同一模块的所有表达式所访问,其他模块的表达式无法访问;全局变量可被所有的表达式所访问。自变量用于向表达式传递参数,因此自变量也称为形式参数。动态变量只在表达式执行时起作用,一旦表达式执行完毕,动态变量也随之失效。静态变量存在于表达式的整个生命周期,每次表达式执行完毕,静态变量的值被保留。Lu在编译表达式时,自变量不进行初始化;动态变量初始化为nil;静态变量初始化为0;模块变量和全局变量在第一次生成时初始化为nil,以后使用不再进行初始化。

    在Lu表达式(函数)中,通常情况下,变量要先定义后使用,变量在表达式的开头进行定义,格式如下:

      F(a,b : x,y,static,u : s,t,common,v)=
      {
        x=1,y=2,
        a+b+x+y+
static+u+s+t+common+v
      }

    F是表达式的名字,a和b是自变量,x和y是动态变量,static和u是静态变量,s和t是模块变量,common和v是全局变量。自变量、动态变量和静态变量以及模块变量和全局变量之间用冒号分隔,即第一个冒号前为自变量,两个冒号之间为动态变量和静态变量,第二个冒号后为模块变量和全局变量。两个冒号之间用关键字static分隔动态变量和静态变量,static之前为动态变量,static及以后变量均为静态变量,关键字static只能用在两个冒号之间。第二个冒号后用关键字common分隔模块变量和全局变量,common之前为模块变量,common及以后变量均为全局变量,关键字common只能用在第二个冒号后。Lu中的所有变量均可缺省。

    C/C++可操作的有意义的Lu脚本变量是模块变量和全局变量,可通过脚本函数操作模块变量和全局变量。

3 代码

    (1)最简单的C/C++存取Lu模块变量的例子

#include <stdio.h>
#include "lu64.h"

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

void main(void)
{
	void *hM1_1,*hM1_2;					//存放表达式句柄,即脚本函数句柄
	luINT nPara;						//存放表达式的自变量个数
	LuData *paraM1_1,*paraM1_2;					//存放输入自变量的数组指针
	LuData Val;						//存放表达式的值
	luINT ErrBegin,ErrEnd;					//表达式编译出错的初始位置和结束位置
	wchar_t M1_1[]=L"set_module_var(x :: mm) = mm=x";		//设置模块1的模块变量
	wchar_t M1_2[]=L"get_module_var(  :: mm) = mm";		//获得模块1的模块变量

	if(!InitLu()) return;		//初始化Lu

	//因表达式都正确,故以下对编译结果都没有进行检查
	LuCom(M1_1,1,0,0,&hM1_1,&nPara,&paraM1_1,&ErrBegin,&ErrEnd);	//编译表达式M1_1为模块1的全局函数
	LuCom(M1_2,1,0,0,&hM1_2,&nPara,&paraM1_2,&ErrBegin,&ErrEnd);	//编译表达式M1_2为模块1的全局函数

	paraM1_1[0].BType=luStaData_int64; paraM1_1[0].VType=luStaData_int64; paraM1_1[0].x=100;
	LuCal(hM1_1,paraM1_1);					//设置模块1的模块变量
	Val=LuCal(hM1_2,paraM1_2);					//获得模块1的模块变量
	printf("模块1的模块变量= %I64d \n",Val.x);

	FreeLu();				//释放Lu
}

运行结果:

模块1的模块变量= 100

    (2)C/C++存取Lu模块变量及全局变量的例子

#include <stdio.h>
#include "lu64.h"

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

void main(void)
{
	void *hM1_1,*hM1_2,*hM1_3,*hM2_1,*hM2_2,*hM2_3,*hM3_1,*hM3_2;	//存放表达式句柄,即脚本函数句柄
	luINT nPara;						//存放表达式的自变量个数
	LuData *paraM1_1,*paraM1_2,*paraM1_3,*paraM2_1,*paraM2_2,*paraM2_3,*paraM3_1,*paraM3_2;//存放输入自变量的数组指针
	LuData Val;						//存放表达式的值
	luINT ErrBegin,ErrEnd;					//表达式编译出错的初始位置和结束位置
	wchar_t M1_1[]=L"set_module_var1(x :: mm) = mm=x";		//设置模块1的模块变量
	wchar_t M1_2[]=L"get_module_var1(  :: mm) = mm";		//获得模块1的模块变量
	wchar_t M1_3[]=L"inc_var1(  :: mm, common, nn) = mm++, nn++";	//模块1的模块变量及全局变量均增1
	wchar_t M2_1[]=L"set_module_var2(x :: mm) = mm=x";		//设置模块2的模块变量
	wchar_t M2_2[]=L"get_module_var2(  :: mm) = mm";		//获得模块2的模块变量
	wchar_t M2_3[]=L"inc_var2(  :: mm, common, nn) = mm++, nn++";	//模块2的模块变量及全局变量均增1
	wchar_t M3_1[]=L"set_common_var1(x :: common, nn) = nn=x";	//模块3设置全局变量
	wchar_t M3_2[]=L"get_common_var1(  :: common, nn) = nn";	//模块3获得全局变量

	if(!InitLu()) return;		//初始化Lu

	//因表达式都正确,故以下对编译结果都没有进行检查
	LuCom(M1_1,1,0,0,&hM1_1,&nPara,&paraM1_1,&ErrBegin,&ErrEnd);	//编译表达式M1_1为模块1的全局函数
	LuCom(M1_2,1,0,0,&hM1_2,&nPara,&paraM1_2,&ErrBegin,&ErrEnd);	//编译表达式M1_2为模块1的全局函数
	LuCom(M1_3,1,0,0,&hM1_3,&nPara,&paraM1_3,&ErrBegin,&ErrEnd);	//编译表达式M1_3为模块1的全局函数
	LuCom(M2_1,2,0,0,&hM2_1,&nPara,&paraM2_1,&ErrBegin,&ErrEnd);	//编译表达式M2_1为模块2的全局函数
	LuCom(M2_2,2,0,0,&hM2_2,&nPara,&paraM2_2,&ErrBegin,&ErrEnd);	//编译表达式M2_2为模块2的全局函数
	LuCom(M2_3,2,0,0,&hM2_3,&nPara,&paraM2_3,&ErrBegin,&ErrEnd);	//编译表达式M2_3为模块2的全局函数
	LuCom(M3_1,3,0,0,&hM3_1,&nPara,&paraM3_1,&ErrBegin,&ErrEnd);	//编译表达式M3_1为模块3的全局函数
	LuCom(M3_2,3,0,0,&hM3_2,&nPara,&paraM3_2,&ErrBegin,&ErrEnd);	//编译表达式M3_2为模块3的全局函数

	paraM1_1[0].BType=luStaData_int64; paraM1_1[0].VType=luStaData_int64; paraM1_1[0].x=1;
	LuCal(hM1_1,paraM1_1);					//设置模块1的模块变量
	paraM2_1[0].BType=luStaData_int64; paraM2_1[0].VType=luStaData_int64; paraM2_1[0].x=2;
	LuCal(hM2_1,paraM2_1);					//设置模块2的模块变量
	paraM3_1[0].BType=luStaData_int64; paraM3_1[0].VType=luStaData_int64; paraM3_1[0].x=3;
	LuCal(hM3_1,paraM3_1);					//设置模块3的全局变量
	LuCal(hM1_3,paraM1_3);					//模块1的模块变量及全局变量均增1
	LuCal(hM2_3,paraM2_3);					//模块2的模块变量及全局变量均增1
	Val=LuCal(hM1_2,paraM1_2);					//获得模块1的模块变量
	printf("模块1的模块变量= %I64d \n",Val.x);
	Val=LuCal(hM2_2,paraM2_2);					//获得模块2的模块变量
	printf("模块2的模块变量= %I64d \n",Val.x);
	Val=LuCal(hM3_2,paraM3_2);					//获得模块3的全局变量
	printf("模块3的全局变量= %I64d \n",Val.x);

	FreeLu();				//释放Lu
}

运行结果:

模块1的模块变量= 2
模块2的模块变量= 3
模块3的全局变量= 5

    (3)C/C++存取Lu模块变量及全局变量的效率测试

#include <stdio.h>
#include <time.h>
#include "lu64.h"

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

__int64 a1,aa2,aaa3,aabb,aabbcc,d1,dd2,ddd3,ddee,ddeeff;

void main(void)
{
	void *hM1_1,*hM1_2,*hM1_3;					//存放表达式句柄,即脚本函数句柄
	luINT nPara;						//存放表达式的自变量个数
	LuData *paraM1_1,*paraM1_2,*paraM1_3;			//存放输入自变量的数组指针
	LuData Val;						//存放表达式的值
	luINT ErrBegin,ErrEnd;					//表达式编译出错的初始位置和结束位置
	wchar_t M1_1[]=L"set(x :: a1,aa2,aaa3,aabb,aabbcc, common,d1,dd2,ddd3,ddee,ddeeff) = a1=x,aa2=x,aaa3=x,aabb=x,aabbcc=x,d1=x,dd2=x,ddd3=x,ddee=x,ddeeff=x";
	wchar_t M1_2[]=L"inc(  :: a1,aa2,aaa3,aabb,aabbcc, common,d1,dd2,ddd3,ddee,ddeeff) = a1++,aa2++,aaa3++,aabb++,aabbcc++,d1++,dd2++,ddd3++,ddee++,ddeeff++";
	wchar_t M1_3[]=L"get(  :: a1,aa2,aaa3,aabb,aabbcc, common,d1,dd2,ddd3,ddee,ddeeff) = a1+aa2+aaa3+aabb+aabbcc+d1+dd2+ddd3+ddee+ddeeff";
	__int64 i;
	clock_t start, end;
	__int64 sum,x;

	if(!InitLu()) return;		//初始化Lu

	//因表达式都正确,故以下对编译结果都没有进行检查
	LuCom(M1_1,1,0,0,&hM1_1,&nPara,&paraM1_1,&ErrBegin,&ErrEnd);	//编译表达式M1_1为模块1的全局函数
	LuCom(M1_2,1,0,0,&hM1_2,&nPara,&paraM1_2,&ErrBegin,&ErrEnd);	//编译表达式M1_2为模块1的全局函数
	LuCom(M1_3,1,0,0,&hM1_3,&nPara,&paraM1_3,&ErrBegin,&ErrEnd);	//编译表达式M1_3为模块1的全局函数

	start = clock();
	paraM1_1[0].BType=luStaData_int64; paraM1_1[0].VType=luStaData_int64; paraM1_1[0].x=0;
	LuCal(hM1_1,paraM1_1);					//设置模块1的模块变量及全局变量
	for(i=0;i<1000000;i++) LuCal(hM1_2,paraM1_2);			//循环执行脚本函数inc若干次
	Val=LuCal(hM1_3,paraM1_3);					//获得模块1的模块变量及全局变量相加的结果
	end = clock();
	printf("C call Lu runing time is %d ms, sum= %I64d \n",(int)(end - start), Val.x);

	start = clock();
	x=0;
	a1=x; aa2=x; aaa3=x; aabb=x; aabbcc=x; d1=x; dd2=x; ddd3=x; ddee=x; ddeeff=x;
	for(i=0;i<1000000;i++)					//循环执行若干次
	{
		a1++; aa2++; aaa3++; aabb++; aabbcc++; d1++; dd2++; ddd3++; ddee++; ddeeff++;
	}
	sum=a1+aa2+aaa3+aabb+aabbcc+d1+dd2+ddd3+ddee+ddeeff;		//获得全局变量相加的结果
	end = clock();
	printf("C runing time is %d ms, sum= %I64d \n",(int)(end - start), sum);

	FreeLu();				//释放Lu
}

运行结果:

C call Lu runing time is 78 ms, sum= 10000000
C runing time is 4 ms, sum= 10000000

4 函数说明

    本例用到了Lu的四个输出函数:初始化Lu的函数InitLu,释放Lu的函数FreeLu,编译表达式的函数LuCom和计算表达式的函数LuCal。从这里查看这些函数的说明:Lu编程指南

5 难点分析

    代码1比较简单,分析从略

    代码2演示了C/C++程序如何存取Lu脚本的模块变量及全局变量。 可以看出,Lu脚本的不同模块中存在同名模块变量时不会相互干扰,但全局变量是唯一的。

    代码3结果表明:C/C++调用Lu脚本函数(存取Lu脚本变量)的效率大致为C/C++效率的1/20~1/50。 如果你对脚本效率感兴趣,请参考:Lu与C/C++、Forcal、MATLAB、Python、Lua等各种语言的速度比较

6 其他

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


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