C/C++对Lu系统内置动态对象进行运算符重载(一)

2014-11-24 07:38:57 · 作者: · 浏览: 2

欢迎访问 Lu程序设计

C/C++对Lu系统内置动态对象进行运算符重载

1 说明

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

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

2 关于运算符重载

在本教程系列的开始,介绍了Lu脚本的基本数据结构(详细参考Lu编程指南),即:

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


基本数据类型BType决定了实际的数据结构,而扩展数据类型VType决定了重载函数。若要对某数据类型VType进行运算符重载,需要用函数LockKey对VType加锁,该函数定义如下:

int _stdcall LockKey(luKEY VType,void (_stdcall *DeleteKey)(void *),luOperator OpLock);

VType:被锁定的键的类型。VType>luPubKey_User(公有键、普通键)或者 VType DeleteKey:删除键值的函数指针,用于标识要加锁的键。该函数由用户定义,但由Lu调用。若DeleteKey=NULL,表示解锁指定的键。
OpLock:luOperator类型的函数指针,用于对象(用指针标识)的运算符重载,该参数不可为NULL。解锁和加锁所用的OpLock函数必须相同。参考 [注1]

如果加锁或解锁成功,该函数返回0,否则返回非0值。

[注1]:运算符重载函数luOperator函数格式如下(与Lu二级函数相比,仅多了一个参数theOperator):

//m指出数组Para的参数个数(也即操作数的个数,0表示1个,1表示2个,以此类推)。
//hFor为调用该函数的表达式句柄(与二级函数中的表达式句柄相同)。
//theOperator指出运算符的类型或操作类型:+、-、*、/、^、... ...。
LuData (_stdcall *luOperator)(luINT m,LuData *Para,void *hFor,int theOperator);

LuData _stdcall OpLock(luINT m,LuData *Para,void *hFor,int theOperator)
{
    //... ...
    switch(theOperator)
    {
    case 0:    //重载运算符+
        //... ...
    case 1:    //重载运算符-
        //... ...
    case 2:    //重载运算符*
        //... ...
    case 3:    //重载运算符%
        //... ...
    case 4:    //重载运算符/
        //... ...
    ... ...
    }
}


如果不打算给加锁的键提供运算符或函数重载功能,须使用函数SetRunErr向Lu报告运行错误。

本文讨论C/C++对Lu系统内置动态对象进行运算符重载。本文的例子来自Lu系统扩展库LuSystem中的Lu表(有改动,有所简化),参考源代码lu1code.rar,实现对Lu系统内置动态对象lu的数据类型扩展luu(基本类型为 luDynData_lu,扩展类型为 key_luu)。

动态对象lu是一个线性表(简称Lu表,可以保存任何数据,包括任意多个lu表),是Lu脚本的基本数据类型,参考C格式的头文件lu32.h,动态对象lu的结构定义如下:

//动态Lu表
typedef struct luLu
{
LuData *Lu; //允许为NULL
luVOID Len; //Lu数据缓冲区长度
} luLu;

Lu表在Lu系统键树中的键值(即基本数据类型BType)为luDynData_lu,参考头文件lu32.h中的定义:

#define luDynData_lu -255 //动态Lu数据

3 代码

#include 
  
   
#include 
   
     #include "lu32.h" #pragma comment( lib, "lu32.lib" ) luKEY key_luu = luPoiKey_User-20; //标识luu的私有键,将对其加锁 void _stdcall Del_luu(void *me) //销毁luu的函数,但什么也不做,只为了配合运算符重载,加锁键使用 { } void _stdcall LuMessage(wchar_t *pch) //输出动态库信息,该函数注册到Lu,由Lu二级函数调用 { wprintf(L"%s",pch); } //Lu脚本可调用的二级函数定义 //生成一个luu对象,注册到Lu脚本系统 LuData _stdcall lu_luu(luINT mm,LuData *xx,void *vFor) { static wchar_t ErrName[]=L"luu"; luINT i; luLu *pLu; LuData a; pLu=(luLu *)NewSysObj(luDynData_lu,mm+1,0); if(!pLu) { a.BType=luStaData_nil; a.VType=luStaData_nil; a.x=0; return a; } for(i=0;i<=mm;i++) pLu->Lu[i]=xx[i]; a.BType=luDynData_lu; a.VType=key_luu; a.x=0; *(luVOID *)&(a.x)=(luVOID)pLu; FunReObj(vFor); return a; } //返回两个luu相加(或者一个luu加其他任意数据)的结果,通过运算符重载间接调用 LuData _stdcall lu_addLuu(luINT mm,LuData *xx,void *vFor) { static wchar_t ErrName[]=L"luu +"; luLu *pLu,*pLu0,*pLu1; luVOID i,j; LuData a; a.BType=luStaData_nil; a.VType=luStaData_nil; a.x=0; pLu0=(luLu *)SearchKey((char *)&(xx->x),sizeof(luVOID),luDynData_lu); pLu1=(luLu *)SearchKey((char *)&((xx+1)->x),sizeof(luVOID),luDynData_lu); if(pLu0 && pLu1 && xx->BType==luDynData_lu && (xx+1)->BType==luDynData_lu) { pLu=(luLu *)NewSysObj(luDynData_lu,pLu0->Len+pLu1->Len,0); if(!pLu) return a; for(i=0,j=0;i
    
     Len;i++,j++) pLu->Lu[j]=pLu0->Lu[i]; for(i=0;i
     
      Len;i++,j++) pLu->Lu[j]=pLu1->Lu[i]; }