欢迎访问 Lu程序设计

在C/C++中使用Lu脚本

目  录

0 概述 简要介绍Lu脚本及基本数据类型。
1 C调用Lu脚本函数 C/C++调用Lu脚本函数的最简单的例子。
2 C模块化编译Lu脚本函数 在Lu中,一个模块由一个或多个表达式(函数)组成。同一模块中,私有表达式只能被本模块的表达式所访问(即调用),在其他模块中是不可见的;公有表达式或全局表达式能被任何一个表达式所访问。
3 对Lu模块进行加锁 加锁一个Lu模块使得其他线程无法向该模块中增加表达式(脚本函数),这在设计多线程程序时特别有用。
4 C操作Lu脚本变量 C/C++读取或设置Lu脚本的变量(全局变量或者模块变量),并测试了存取效率。
5 C注册常量或函数到Lu系统 C/C++注册常量或函数到Lu脚本系统,这些常量或函数可在Lu脚本系统中使用。本例中对Lu函数的返回值进行了检查。
6 C接收Lu系统的字符串信息 C/C++接收Lu系统的字符串信息,这些信息来自于函数o,或者来自注册到Lu的二级函数。
7 C使用Lu脚本中的动态对象lu 介绍动态对象与静态对象的区别,以动态对象lu为例,介绍C/C++如何使用Lu脚本的动态对象 ,介绍了Lu键树基础知识。
8 C使用Lu脚本字符串 介绍C/C++程序如何使用Lu脚本字符串(静态字符串和动态字符串)。
9 C使用Lu脚本数组 介绍C/C++程序如何使用Lu脚本数组(静态数组和动态数组)。
10 C使用Lu脚本字符串键树 Lu脚本所有的数据都存储在Lu字符串键树中;C/C++程序可单独使用该键树管理自己的数据。
11 C++使用Lu键树实现智能指针 使用Lu字符串键树可帮助C/C++程序实现自动内存回收机制以及方便检查内存泄露,并测试了运行效率。
12 使用C给Lu静态类型数据添加运算符重载功能 使用C/C++给Lu静态类型数据添加运算符重载功能。
13 C注册动态对象到Lu系统并进行运算符重载 C/C++注册动态对象到Lu系统,同时进行运算符重载。 演示了二级函数如何返回一个动态对象;演示了二级函数如何通过参数返回多个动态对象;演示了重载函数new、oset、oget、o的用法;演示了 编译符#在系统扩展中的作用(如何由字符串获得一个唯一的整数,以及该整数在Lu脚本中如何使用);演示了如何在Lu系统中注册常量和函数;演示了如何接收Lu系统的字符串信息等等。
14 C对Lu系统内置动态对象进行运算符重载 C/C++对Lu系统内置动态对象进行运算符重载。
15 C使用Lu脚本协程 C/C++使用Lu脚本协程。
16 使用C设计Lu脚本函数时调用Lu脚本函数 使用C/C++设计Lu脚本函数时调用Lu脚本函数,演示了Lu表达式句柄的用法,演示了如何向Lu系统报告运行错误。
17 设计多线程程序监控Lu脚本运行 使用C/C++设计多线程程序监控Lu脚本运行;同时演示了如何获取Lu运行错误。
18 C程序使用lu对象(lu表)作为配置文件 C/C++程序使用lu对象(lu表)作为配置文件。演示了如何解析lu对象,演示了编译符#的用法。
19 用C++设计Lu扩展动态库 用C/C++设计Lu扩展动态库 。虽然主程序可以方便地对Lu系统进行扩展,但使用Lu扩展动态库进行扩展更具有一般性和更大的灵活性。
20 C++使用Lu扩展动态库 介绍C/C++如何使用Lu扩展动态库。
21 用C++设计Lu结构、字典、类等高级数据类型 用C/C++设计Lu结构、字典、类等高级数据类型 。很少有脚本允许用户能方便地添加像字典、结构、类等高级的数据结构,但Lu允许,而且实现这些很容易。
22 C++使用MLu简化Lu脚本系统的使用 C/C++使用MLu简化Lu脚本系统的使用。MLu是程序和Lu核心库之间的一个接口库,MLu会自动加载Lu核心库和动态加载多个Lu扩展库,简化了Lu系统的使用;MLu可对Lu源程序进行模块化编译,能够编译运行具有固定格式的源程序(字符串表达式),源程序中可以使用C++风格的注释。此外,MLu还提供了多个线程互斥地访问Lu资源的功能;提供了Lu运行监视器,以退出耗时较长的程序;提供在脚本中动态编译函数的功能;提供错误处理函数,实现错误(异常)处理的恢复模型等等。
23 在Win32SDK中使用Lu模块化编译运行库MLu 演示如何在Windows程序中加入Lu脚本支持,比较快捷的方式是通过MLu使用Lu脚本。图示说明 如何在Win32SDK中使用Lu模块化编译运行库MLu。下载源代码SDKTestMLu.rar。 如果希望得到一个语法高亮的编辑器,可下载源代码RICHEDTestMLu.rar

0 概述

    说到Lu,很多人会联想到Lua,但Lu与Lua除了都是脚本之外,其他一点关系都没有。Lu是一个可对字符串表达式进行动态编译和运行的动态链接库(dll),是一种易于扩展的轻量级嵌入式脚本,Lu的优势在于简单易用和可扩展性强,可用于各类数学软件的设计,也可用作报表处理、web、组态软件、游戏等的脚本,具有很高的执行效率。

    Lu使用stdcall调用协议输出了动态库函数,可供C/C++、VB、delphi、FORTRAN等程序使用。但受水平和精力所限,本文仅提供C/C++与Lu交互的例子。

    本教程系列通过实例,介绍如何在C/C++中使用Lu脚本。通过本教程系列,可以了解到C/C++程序是如何与Lu进行交互的,包括C/C++程序如何调用Lu的函数、如何访问Lu的变量,C/C++程序如何注册函数到Lu脚本系统(也就是Lu脚本如何调用C/C++函数),C/C++程序如何注册对象到Lu系统,这些对象是如何使用和管理的,C/C++如何使用Lu键树管理自己的动态数据,等等。

    当前,脚本语言种类繁多,如Lua、Python、Go、PHP、JavaScript、VBscript等等,我相信各种脚本会各有各的用途。我将尽可能地将Lu脚本的用途体现在本教程系列里。

    要演示本教程的例子,你必须下载Lu32脚本系统,很明显,这是32位的Lu脚本系统,本教程系列的例子都是基于32位系统的。当然,稍加修改,这些例子就可以用于64位系统,你可以下载Lu64脚本系统进行尝试。

    以下资料不是必须的,但对理解本教程有帮助:

    (1)在控制台程序中演示Lu脚本的步骤图示:在C中使用Lu脚本步骤图示在C++中使用Lu脚本步骤图示

    (2)实用程序OpenLu:用于演示Lu脚本的语法。OpenLu非常小巧,目前只有5M左右,是免安装的绿色软件。

    (3)Lu脚本系统说明虽然前面的Lu32脚本系统和OpenLu都包含了该说明,但你可以从这里快速浏览。

    (4)Lu编程指南:Lu核心库(lu32.dll)输出函数的说明,本教程系列将在实例中展示这些函数的使用。虽然前面的Lu脚本系统中也包含了该说明,但你可以从这里快速浏览。

    在开始例子之前,我还要介绍Lu的基本数据类型,这是使用Lu编程最基础的东西。

    Lu脚本中会存在许多类型的数据,如整数、实数、字符串、逻辑值、函数句柄、对象等等,但在其内部实现上,所有的数据类型都使用同一种结构形式,即:

struct LuData{    //Lu基本数据结构。
    luIFOR x;    
//luIFOR被定义为64位整数__int64,用于存放数据。对于动态数据类型,对象指针约定保存在x的前4个字节中
    luIFOR y;    
//存放数据。
    luIFOR z;    
//存放数据。
    luKEY  VType;
//luKEY被定义为32位整数__int32。扩展数据类型,决定重载函数,从而决定了对数据的操作方式。
    luKEY  BType;
//基本数据类型,决定了Lu数据的结构。
};

    任何Lu数据在赋值时,必须提供基本数据类型BType和扩展数据类型VTypeBType决定了实际的数据结构;VType指出要调用哪一个重载函数(需要专门的篇章对VType作介绍,这里先忽略它)。常见的BType见下表0-1(表中看不懂的部分先不管它,以后用到的时候我们再进行介绍):

表0-1 Lu基本数据类型BType

类别 基本数据类型BType Lu头文件中定义的标识符 LuData::x LuData::y LuData::z 意 义
静态类型 0 luStaData_nil       未定义的Lu数据或操作失败
1 luStaData_forhandle 前32位保存指针     表达式句柄。
2 luStaData_int64 64位整数     64位整数
3 luStaData_double 双精度实数     64位双精度实数
4 luStaData_complex 复数实部 复数虚部   复数
5 luStaData_vector x y z 三维向量
系统定义动态类型
-252 luDynData_realarray 前32位保存指针     动态64位实数数组
-253 luDynData_intarray 前32位保存指针     动态64位整数数组
-254 luDynData_string 前32位保存指针     动态字符串
-255 luDynData_lu 前32位保存指针     动态Lu数据
用户定义动态类型 < -256 < luPriKey_User 前32位保存指针     用户自定义的私有动态数据类型,均小于-256
> 256 > luPubKey_User 前32位保存指针     用户自定义的公有动态数据类型,均大于256

    Lu基本数据结构中,数据区占192位,共24个字节。能够用这24个字节表示的数据称为静态类型数据,例如Lu脚本中的整数(8字节)、实数(8字节)、复数(16字节)、三维向量(24字节)等都是简单数据。设a是一个Lu整数数据,其赋值格式如下:

a.x = 1;                     //赋值为1。
a.
BType = luStaData_int64;   //基本数据类型为整数。
a.VType = luStaData_int64;   //扩展数据类型为luStaData_int64(需要专门的篇章对VType作介绍,这里先忽略它)。

如果a是一个Lu复数数据,其赋值格式如下:

*(double *)&(a.x) = 1.0;     //实部赋值为1.0。
*(double *)&(a.y) = 2.5;
     //虚部赋值为2.5。
a.
BType = luStaData_complex; //基本数据类型为复数。
a.VType = luStaData_complex; //扩展数据类型为luStaData_complex。

    你可能会说,赋值好麻烦嘛。嗯,Lu是强类型的脚本,可以精细地识别各种数据类型,鱼与熊掌不可兼得哦。

    静态类型数据是简单数据类型,最多存放24个字节的数据,如果数据再大该怎么办?例如字符串、数组等数据类型,在Lu脚本中该如何表示呢?类似于字符串、数组等占用字节数可多可少,或者占用字节数超过24的数据,Lu脚本中称之为动态数据类型(或者称为动态对象)。对于动态对象,在Lu基本数据结构LuData中只保存动态对象的指针,如表0-1所示,对象的32位指针保存在LuData::x的前32位中。关于动态对象及操作,以及如何注册C/C++动态对象到Lu系统,又是一个较大的话题,以后会有专门的篇章作介绍,这里就不展开了。

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


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