Rise的自留地

记录生活中的点滴,分享编程技术和游戏开发经验。

0%

【肇法师曰】闻说诸心。谓有实心。故须破遣。明三世皆空。故论云。过去已灭。未来未起。现在虚妄。三世推求。了不可得。

      【疏钞云】未觉不知。随时流转。故有三世。若悟真一之心。即无过去现在未来。若有过去心可灭。即是自灭。若有未来心可生。即是自生。既有生有灭。即非常住真心。即为依他心。虚妄心。若一念有生灭心。即成六十二种邪见。九百种烦恼。

      【王日休曰】常住真心。即真性也。是以自无量无数劫来。常一定而不变动。岂有过去未来现在哉。若有过去未来现在。则为妄想。此三心是也。且若饱而未欲食。则饮食之心为未来。饥而正欲食。则欲食之心为现在。食毕而放匕箸。则欲食之心为过去。是此心因事而起。事过而灭。故为妄想也。不可得者。谓无也。言此三心本来无有。乃因事而有耳。圆觉经所以言六尘缘影。为自心相者。谓众生以六种尘缘之影。为自己之心相也。

      【僧若讷曰】本生心地观经云。如佛所说。唯将心法。为三界主。心法本源。不染尘秽。云何心法。染贪嗔痴。于三世法。唯说为心。过去心已灭。未来心未至。现在心不住。诸法之内性不可得。诸法之外相不可得。诸法中间都不可得。心法本来无有形相。心法本来无有住处。一切如来尚不可见心。何况余人。得见心法。

      【颜丙曰】谓思念前事者。为过去心。思念今事者。为现在心。思念后事者。为未来心。三念总放下者。谓之不可得。经云。前念后念及今念。念念不被邪见染。此为三心不可得。古云。一念不生全体现。亦谓三际俱断。三念俱妄。了不可得。

      【傅大士颂曰】依他一念起。俱为妄所行。便分六十二。九百乱纵横。(法华经二卷。世尊偈言。薄德少福人。众苦所逼迫。入邪见稠林。若有若无等。依止此诸见。具足六十二。毗婆沙论云。六十二见者。五蕴中各起四见。四五二十。三世各二十。通为六十。断常二见为根本。总为六十二见。且于色蕴中。即色是我。离色非我。我中有色。色中有我。五蕴中具有此四。疏钞解三心云。若一念有生灭心。即成六十二种邪见。九百种烦恼。)过此灭无灭。(一作不灭。)当来生不生。常能作此观。(去声)真妄坦然平。(晁文元公遇高士刘惟一。访以生灭之事。刘曰。人常不死。公骇之。刘曰。形死性不灭。是知此性历长存。)

      【川禅师曰】低声低声。真得鼻孔里出气。颂曰。三际求心心不见。两眼依然对两眼。不须遗剑刻舟寻。雪月风花常见面。

      【未曾有经云】妙吉祥菩萨。因见一人。言我造杀业。决堕地狱。如何救度。菩萨即化一人。亦曰。我造杀业。决堕地狱。前人闻已。言我亦然。化人告之。唯佛能救。相随共诣。化人白佛。我造杀业。怖堕地狱。愿佛救度。佛即告言。如汝所说造杀业者。汝从何心而起业相。为过去耶。未来耶。现在耶。若起过去心者。过去已灭。心不可得。若起未来心者。未来未来。心不可得。若起见在心者。见在不住。心不可得。三界俱不可得故。即无起作。无起作故。于其罪相何所见耶。善男子。心无所住。不在内外中间。心无色相。非青黄赤白。心无造作。无作者故。心非幻化。本真实故。心无边际。非限量故。心无取舍。非善恶故。心无转动。非生灭故。心等空虚。无障碍故。心非染净。离一切数故。善男子作是观者。即于一切法中。求心不可得。何以故。心之自性。即诸法性。诸法性空。即真实性。由是义故。汝今不应妄生怖畏。是时化人闻佛说法。即白佛言。我今得悟罪业性空。不生怖畏。尔时实造业者。亦白佛言。我今得悟罪业性空。而不复生怖畏之心。

      【李文会曰】谓三世心无性可得。故可从缘而生。

      【肇法师云】闻说诸心。谓有实心。故须破遣。明三世皆空。故云过去已灭。未来未起。现在虚妄。三世推求。了不可得。故云若悟无法无相无事平常真心。即法体空寂。不生不灭。湛然清净。岂有前念今念后念可得也。

      【马祖云】道不用修。但莫洿染。何谓洿染。但有生死造作趣向。皆是洿染。若欲直会其道。平常心即是道。何谓平常心。无造作。无是非。无取舍。无憎爱。无圣凡。是故经云。非凡夫行。非圣贤行。是菩萨行。

      【赵州问南泉云】如何是道。泉云。平常心是道。

      【圜悟禅师颂曰】欲识平常道。天真任自然。行船宜举棹。走马即加鞭。若遇饥来饭。还应困即眠。尽从缘所得。所得亦非缘。

根据文件句柄,获取文件名

#include <windows.h>

#include <stdio.h>

#include <tchar.h>

#include <string.h>

#include <psapi.h>

 

#define BUFSIZE 512

 

BOOL GetFileNameFromHandle(HANDLE hFile) 

{

  BOOL bSuccess = FALSE;

  TCHAR pszFilename[MAX_PATH+1];

  HANDLE hFileMap;

 

  // Get the file size.

  DWORD dwFileSizeHi = 0;

  DWORD dwFileSizeLo = GetFileSize(hFile, &dwFileSizeHi); 

 

  if( dwFileSizeLo == 0 && dwFileSizeHi == 0 )

  {

     printf("Cannot map a file with a length of zero.\n");

     return FALSE;

  }

 

  // Create a file mapping object.

  hFileMap = CreateFileMapping(hFile, 

                    NULL, 

                    PAGE_READONLY,

                    0, 

                    1,

                    NULL);

 

  if (hFileMap) 

  {

    // Create a file mapping to get the file name.

    void* pMem = MapViewOfFile(hFileMap, FILE_MAP_READ, 0, 0, 1);

 

    if (pMem) 

    {

      if (GetMappedFileName (GetCurrentProcess(), 

                             pMem, 

                             pszFilename,

                             MAX_PATH)) 

      {

 

        // Translate path with device name to drive letters.

        TCHAR szTemp[BUFSIZE];

        szTemp[0] = '\0';

 

        if (GetLogicalDriveStrings(BUFSIZE-1, szTemp)) 

        {

          TCHAR szName[MAX_PATH];

          TCHAR szDrive[3] = TEXT(" :");

          BOOL bFound = FALSE;

          TCHAR* p = szTemp;

 

          do 

          {

            // Copy the drive letter to the template string

            *szDrive = *p;

 

            // Look up each device name

            if (QueryDosDevice(szDrive, szName, BUFSIZE))

            {

              UINT uNameLen = _tcslen(szName);

 

              if (uNameLen < MAX_PATH) 

              {

                bFound = _tcsnicmp(pszFilename, szName, 

                    uNameLen) == 0;

 

                if (bFound) 

                {

                  // Reconstruct pszFilename using szTemp

                  // Replace device path with DOS path

                  TCHAR szTempFile[MAX_PATH];

                  _stprintf(szTempFile,

                            TEXT("%s%s"),

                            szDrive,

                            pszFilename+uNameLen);

                  _tcsncpy(pszFilename, szTempFile, MAX_PATH);

                }

              }

            }

 

            // Go to the next NULL character.

            while (*p++);

          } while (!bFound && *p); // end of string

        }

      }

      bSuccess = TRUE;

      UnmapViewOfFile(pMem);

    } 

 

    CloseHandle(hFileMap);

  }

  printf("File name is %s\n", pszFilename);

  return(bSuccess);

}

开机自动运行

  其中strPath参数表示要设置为自运行的程序的绝对路径。当设置成功时返回true,否则返回false

BOOL SetAutoRun(CString strPath)//开机自动运行

{

   CString str;

   HKEY hRegKey;

   BOOL bResult;

   str=_T("Software\\Microsoft\\Windows\\CurrentVersion\\Run");

   if(RegOpenKey(HKEY_LOCAL_MACHINE, str, &hRegKey) != ERROR_SUCCESS) 

       bResult=FALSE;

   else

   {

       _splitpath(strPath.GetBuffer(0),NULL,NULL,str.GetBufferSetLength(MAX_PATH+1),NULL);

       strPath.ReleaseBuffer();

       str.ReleaseBuffer();

       if(::RegSetValueEx( hRegKey,

                           str,

                           0,

                           REG_SZ,

                           (CONST BYTE *)strPath.GetBuffer(0),

                           strPath.GetLength() ) != ERROR_SUCCESS)

          bResult=FALSE;

       else

          bResult=TRUE;

       strPath.ReleaseBuffer();

   }

   return bResult;

}        

 

使计算机休眠

void XiuMian() 

{

 if(MessageBox("确实要休眠吗?","关机程序",MB_YESNO|MB_DEFBUTTON2|MB_ICONQUESTION)==IDYES)

 {

  HANDLE hToken;

  TOKEN_PRIVILEGES tp;

  LUID luid;

  if(::OpenProcessToken(GetCurrentProcess(),

         TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY,

         &hToken))

  {

   ::LookupPrivilegeValue(NULL,SE_SHUTDOWN_NAME,&luid);

   tp.PrivilegeCount=1;

   tp.Privileges[0].Luid =luid;

   tp.Privileges[0].Attributes =SE_PRIVILEGE_ENABLED;

   ::AdjustTokenPrivileges(hToken,false,&tp,sizeof(TOKEN_PRIVILEGES),NULL,NULL);

  }

  ::SetSystemPowerState(false,true); 

 }

}

本来不想写这篇很挨打的Post,不过在最近几天的最热的几篇Post里面看到无数的Tx为了面向对象的争论,感触颇多,遂作此篇。
鄙视OO的也进来鄙视我吧。望OO达人多多指正。

前头有一篇关于对象持久化的。不过很多Tx,连OO都不理解,那么持久化也是空谈。
我们首先抛弃千篇一律的什么对象来源于生活,是真是对象的程序表现的屁话,空洞,对于一个一接触程序就开始过程,将严谨的过程渗透到骨髓里的工程人员来说,跟他扯这个简直是对牛谈琴。所以我们从过程来讲对象,然后来看如何将过程化的思维方式转化到对象式的方法论。以及过程抽象的弊端以及为什么要在复杂系统里OO。
我们不能否认,我们在描述一件事情的时候,可以按照过程的方式进行抽象。打个比方。
=======================
将一个表单存入数据库
=======================
按照过程的方式描述。
1.一条条读取表单上字段的值
2.根据值构建SQL语句
3.创建链接
4.创建命令
5.执行命令
6.关闭链接
基本上也就6步就完成了,没有多余的步骤。同意?

那么接下来我们把这个命题扩展到两个表单乃至N个表单,那么这个过程就会N倍的扩张。于是过程达人们就开始动脑筋了。于是开始了第一个迭代的抽象(根据怪怪的理论,我们认同过程的抽象)。我们把构建SQL语句的部分过程抽象出来成了单独的过程-[构建Sql语句]。再一看,我们其实对执行SQL都可以抽象,于是将3,4,5,6都抽象出来,于是SqlHelper诞生了。

这就是过程抽象的方式,不可否认其实我们很多人都经历过这个阶段。而且对此很为困惑。如果所做的很简单,过程很短,那么看起来过程的抽象方式确实更加容易理解。但是我们来看看过程的噩梦在那里。

我们继续扩充命题。
现在我们提交一个表单需要提交到两个数据库。于是我们的N个表单又产生更多的子过程。随着单个过程的长度增加,我们抽象出来的子过程还可能抽象出子过程,结果抽象出来的子过程呈级数增加。直到你的脑袋爆掉。
还有一个问题就是,我们抽象出来的子过程放哪里?C#是一个面向对象的语言,所有的过程(或者函数,方法)都是从属于类,于是就出现了一个巨大的类包含无数静态方法的怪胎。

那么,我们来看面向对象。面向对象和过程有什么联系呢。其实程序最终的运行还是按照过程的,类的作用就像一个框框,指定了那个过程应该属于那个类,必须在存在对象的时候才能调用还是在类中调用。之前在过程的时候抽象出的一大堆子过程杂乱无章。但是在用面向对象的方法所抽象出来的对象确实井然有序的。
对象在执行的时候是按照一定的时序和过程在执行(所以在UML里有时序图)。但是我们不能够因为计算机是按照过程在执行就否定了OO,因为OO是设计时的概念(所以只有OOA、OOD、OOP而没有OOR【面向对象执行-自我发明的词,不存在此物】),而OO的过程是在设计的时候自然而然的产生的,既然OO的语言都存在,那么在这么多年的实践中,证明OO的方法是行之有效的。

下面我们来看如何OO。
用一个很简单的例子,聊天室,不用数据库的,数据记录在内存。
 

闲话不说了,看代码:

 1#define PROTECTED_DACL_SECURITY_INFORMATION (0x80000000L)
 2
 3BOOL Lock_CurrentProcess()
 4{
 5  HANDLE hProcess = ::GetCurrentProcess();
 6  SID_IDENTIFIER_AUTHORITY sia = SECURITY_WORLD_SID_AUTHORITY;
 7  PSID pSid;
 8  BOOL bSus = FALSE;
 9  bSus = ::AllocateAndInitializeSid(&sia,1,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&pSid);
10  if(!bSus) goto Cleanup;
11  HANDLE hToken;
12  bSus = ::OpenProcessToken(hProcess,TOKEN_QUERY,&hToken);
13  if(!bSus) goto Cleanup;
14  DWORD dwReturnLength;
15  ::GetTokenInformation(hToken,TokenUser,NULL,NULL,&dwReturnLength);
16  if(dwReturnLength > 0x400goto Cleanup;
17  LPVOID TokenInformation;
18  TokenInformation = ::LocalAlloc(LPTR,0x400);//这里就引用SDK的函数不引用CRT的了
19  DWORD dw;
20  bSus = ::GetTokenInformation(hToken,TokenUser,TokenInformation,0x400,&dw);
21  if(!bSus) goto Cleanup;
22  PTOKEN_USER pTokenUser = (PTOKEN_USER)TokenInformation;
23  BYTE Buf[0x200];
24  PACL pAcl = (PACL)&Buf;
25  bSus = ::InitializeAcl(pAcl,1024,ACL_REVISION);
26  if(!bSus) goto Cleanup;
27  bSus = ::AddAccessDeniedAce(pAcl,ACL_REVISION,0x000000FA,pSid);
28  if(!bSus) goto Cleanup;
29  bSus = ::AddAccessAllowedAce(pAcl,ACL_REVISION,0x00100701,pTokenUser->User.Sid);
30  if(!bSus) goto Cleanup;
31  if(::SetSecurityInfo(hProcess,SE_KERNEL_OBJECT,DACL_SECURITY_INFORMATION | PROTECTED_DACL_SECURITY_INFORMATION,NULL,NULL,pAcl,NULL) == 0)
32    bSus = TRUE;
33Cleanup:
34  if(hProcess != NULL)
35    ::CloseHandle(hProcess);
36  if(pSid != NULL)
37    ::FreeSid(pSid);
38  return bSus;
39}

40


这段代码就可以锁住其他进程打开本进程,当然也就防止了注入,和读写内存.

可以更绝点Denied ALL ACCESS(0xFFFFFFFF)就连结束都不可能了

::AllocateAndInitializeSid 可以换成 :: InitializeSid .因为我们并不需要初始化子Sid.
另外.
  bSus = ::AddAccessDeniedAce(pAcl,ACL_REVISION,0x000000FA,pSid);
  if(!bSus) goto Cleanup;
  bSus = ::AddAccessAllowedAce(pAcl,ACL_REVISION,0x00100701,pTokenUser->User.Sid);
实际上只需要下面的一句,或者干脆把它去掉,因为如果不添加Ace默认就是没有权限.既然这样上面的那句话AllocateAndInitializeSid 也可以省掉,也似乎有些多余

作者: Roberto Ierusalimschy, Luiz Henrique de Figueiredo, Waldemar Celes

Copyright © 2003 Tecgraf, PUC-Rio. All rights reserved.

译者: ShiningRay Nicholas @ NirvanaStudio

给予支持


1 - 绪论

Lua是一种为支持有数据描述机制的一般过程式编程语言而设计的扩展编程语言。它同样可以对面向对象语言、函数式程序设计(Functional Programming,如Lisp)以及数据驱动编程(data-driven programming)提供很好的支持。它的目标是被用作一种强大的、轻型的配置语言。Lua目前已经被实现为一个扩展库,是用_clean_ C (ANSI C/C++的一个通用子集)编写的。

去年我作了一个Lua脚本的C++包装,有许多朋友感兴趣,并尝试使用,我感到受宠若惊。事实上,我作的包装,学习的目的比较强,它还是有许多缺陷的。为了让朋友们少走弯路,我推荐使用LuaPlus作为C++的包装。

虎鹤双形拳是南海平洲人林世荣根据洪拳和佛拳改编而成一套拳术。著有《虎鹤双形》一书。他说这套拳能“以小击大,以弱击强,千斤之力得以半两消之”; 又说,能“以横克直,以弱借强,虎爪则如猛虫扑兽,鹤翅则为凌空击水,浩浩如五爪金龙,盘盘如老僧入定,极神化之妙”。自成一格,有“洪头佛尾”之称。流行于南海、番禺、顺德、肇庆、广宁、怀集等地,流行于港澳和南洋一带。它的整套动作108点,模仿虎与鹤两种形象编成。结构有慢有快,有高有低,从慢到快,快慢结合。其内容以洪家桥马、佛家快打、洪家防卫、佛家攻势兼而有之。手形是拳、掌、指、爪、钩。手法有抛、钉(钑)、挂、撞、插。步法有弓步、马步、虚步、跪步、独立步和麒麟步。身形以平稳中正为主,收腹探身为助。拳势威武雄壮,气势磅礡。要求出拳稳定有力,步法落地生根,眼睛灵活有神,身段挺拔端正。





可惜没学玩有空继续。

为什么要用Lua作脚本?
  使用Lua作脚本,主要是因为它小巧玲珑(体积小,运行快),而且它的语法又比较简单明了。不过,使用LuaAPI将Lua引擎集成到程序中,确实有一些不方便——用落木随风网友的话来说,就是"就象用汇编"。当然,现在你不用再这么辛苦了,因为你可以使用LuaWrapper For C++。使用这个工具,在C++中集成Lua脚本就是轻而易举的事。你原有的C++函数和类,几乎不需要任何改变,就可以与Lua脚本共享。
  我们接下来,用实例来说明,如何用LuaWrapper来集成Lua脚本到你的程序中去。

1.  创建Lua引擎
  LuaWrap lua; 或者 LuaWrap* lua = new LuaWrap;
  创建一个LuaWrap对象,就是创建一个Lua脚本引擎。并且根据Lua的特性,你可以创建任意多个Lua引擎,甚至可以分布在不同的线程当中。

2.  装载并执行脚本程序
  你可以从缓冲区中装载Lua脚本:
  lua.LoadString(
    "print('Hello World')"
  );
  当然,你也可以从文件中装入,并执行Lua脚本:
  Lua.LoadFile("./test.lua");
  Lua的脚本,可以是源代码,也可以经过编译后的中间代码。也许你对编译后的中间代码更感兴趣——如果你不希望让源代码赤裸裸的袒露在大家的眼前。

3.  获取和设置Lua变量
  能够获取和设置脚本变量的内容,是一个最基本的功能。你可以使用GetGlobal和SetGlobal函数来做到这一点:
  (1)  获取变量:
    int a = lua.GetGlobal<int>("a");
    LuaTable table = lua.GetGlobal<LuaTable>("t");
    这里,<> 里头的类型,就是想要的变量的类型。
  (2)  设置变量:
    lua.SetGlobal("a", a);
    lua.SetGlobal("t", table);

4.  调用Lua函数
  使用Call函数,就可以很简单的从你的程序中调用Lua函数:
  lua.Call<void>("print", "Hello World");
  int sum = lua.Call<int>("add", 2, 3);
  这里,<> 里头的类型是返回值的类型。

5.  如何让Lua也能调用C++的函数
  精采的地方来了。假如有下面这样的一个函数:
  int add(int a, int b)
  {
    return a + b;
  }
  如果想让它能够让Lua使用,只需将它注册到Lua引擎当中就可以了:
  lua.RegisterFunc("add", int(int,int), add);
  这样,Lua中就可以用直接使用了:
  (Lua脚本)sum = add(1, 3)

  (*) RegisterFunc的功能,就是让你把C++的函数注册到Lua中,供Lua脚本使用。
    第一个参数,是想要在Lua中用的函数名。
    第二个参数,是C++中函数的原型; C++允许函数重载的,你可以使用函数原型,来选择需要注册到Lua引擎中的那个函数。
    第三个参数,就是C++中函数的指针了。

6.  如何能让C++的类在Lua中使用
  我们先看看下面这个C++类:
class MyArray
{
  std::vector<double> array;
public:
  void setvalue(int index, double value);
  double getvalue(int index);
  int size();
  const char* ToString();
};

  你准备要让Lua能够自由访问并操作这个类。很简单,你只需增加几个宏定义就可以了:

class MyArray
{
  std::vector<double> array;
public:
  void setvalue(int index, double value);
  double getvalue(int index);
  int size();
  const char* ToString();
  // 将一个 class 作为一个 Lua 对象是很容易的,只需要增加以下宏定义。
  DEFINE_TYPENAME("My.array");
  BEGIN_REGLUALIB("array")
      LUALIB_ITEM_create("new", MyArray )  // 创建MyArray (注:由于发表的原因,create应为全部大写)
      LUALIB_ITEM_DESTROY("del", MyArray )  // 消除MyArray。
  END_REGLUALIB()
  BEGIN_REGLUALIB_MEMBER()
    LUALIB_ITEM_FUNC("size", int (MyArray*), &MyArray::size)
    LUALIB_ITEM_FUNC("__getindex", double(MyArray*, int), &MyArray::getvalue)  
    LUALIB_ITEM_FUNC("__newindex", void (MyArray*, int, double), &MyArray::setvalue)
    LUALIB_ITEM_FUNC("__tostring", const char* (MyArray*), &MyArray::ToString)
    LUALIB_ITEM_DESTROY("__gc", MyArray )   // 垃圾收集时消除对象用。
  END_REGLUALIB_MEMBER()
};

  只要有了这些宏定义,这个类就是可以在Lua中使用的类了,我们就可以在Lua中注册这个类了:
  lua.Register<MyArray>()

  这样注册以后,我们在Lua中就可以使用这个类了:
  a = array.new()  -- 创建对象,相当于 a = new Myarray
  a[1] = 10  -- 调用__newindex,也就是C++中的 a->setvalue(1, 10)
  a[2] = 20  -- 调用__newindex,也就是C++中的 a->setvalue(2, 20)
  print(
    a,  -- 调用 __tostring,也就是C++中的 a->ToString()
    a:size(), -- 相当于C++中的 a->size()
    a[1], -- 调用__getindex,也就是C++中的a->getvalue(1)
    a[2]) --调用__getindex,也就是C++中的a->getvalue(2)
  array.del(a)  -- 清除对象,相当于 delete a
  a = nil  -- 清空 a,很象C++中的 a = NULL

  当然,你也可以不用del这个对象,而是等待Lua帮你自动进行垃圾回收。在Lua进行垃圾回收时,它会自动调用这个对象的 __gc ,相当于 delete。

  那么,在C++中要创建MyArray对象,并且传递给Lua全局变量怎么办?就象前面讲过的一样,使用SetGlobal:
  MyArray* a = new MyArray;
  lua.SetGlobal("a", a);
  要获取该对象,同样的,应该使用GetGlobal:
  MyArray* a = lua.GetGlobal<MyArray>("a");
  
  对于传递给Lua的对象,就让Lua来管理该对象的生存周期好了。如果你非要删除它的话,你可以使用DelGlobalObject:
  lua.DelGlobalObject<MyArray>("a");
  不过这么做的话,你应当明白你在做什么,因为在Lua的脚本中,可能已经在多处引用了这个对象了。删除了其中一个,将导致其它引用对象失效,从而可能引致系统崩溃。

  (1)  DEFINE_TYPENAME("My.array");
    定义类型的名称。在Lua中,这个类型名称是唯一用来识别C++类型的,你必须为不同的对象给予不同的名称。

  (2)  BEGIN_REGLUALIB("array") … END_REGLUALIB()
    你可以为一个对象定义一个程序库,"array"就是程序库的名字。在程序库中定义的函数是全局函数,在Lua中,使用该函数,需要在函数前加上库的名字,如:array.new()。通常,程序库会包含创建对象的方法。如:
    LUALIB_ITEM_create("new", MyArray )  // 创建MyArray (注:由于发表的原因,create应为全部大写)
    这样子,你才能在Lua中创建MyArray:
    a = array.new()
  
    你也可以选择增加一个删除对象操作:
    LUALIB_ITEM_DESTROY("del", MyArray )   // 删除MyArray
    这样,你就可以直接删除一个对象了:
    array.del(a)

  (3)  BEGIN_REGLUALIB_MEMBER() …END_REGLUALIB_MEMBER()
    在此处,你可以定义对象的成员函数,也可以重载对象的操作符——是的,就象C++的operator重载。例如:
    LUALIB_ITEM_FUNC("__newindex", void (MyArray*, int, double), &MyArray::setvalue)
    就是重载 operator[] 操作符。Lua中可重载的操作符还有许多,如:

    __getindex:操作符[],支持读取访问,如 v = a[10]
    __newindex:操作符[],支持赋值访问,如 a[10] = 1.22
    __tostring:将变量转换成字串__add:等同于operator +
    __add:操作符 +
    __sub:操作符 –
    __mul:操作符 ×
    __div:操作符 ÷
    __pow:操作符 ^ (乘方)
    __unm:一元操作符 –
    __concat:操作符 .. (字符串连接)
    __eq:操作符 == (a ~= b等价于 not a == b)
    __lt:操作符 < (a > b 等价于 b < a)
    __le:操作符 <= (a >= b 等价于 b <= a,要注意的是,如果没有定义"__le",则Lua将会尝试将a<=b 转换成 not (b < a) )

    __gc:在垃圾回收时调用此函数,相当于C++的析构函数。强烈建议定义此操作符,以免造成内存泄漏等情况。比如:
    LUALIB_ITEM_DESTROY("__gc", MyArray )   // 垃圾收集时消除对象用。

    (注) 这里要说明一下,在lua中,访问索引操作符是__index,不是__getindex,在luaWrapper库中,为了方便使用,将其映射为__getindex,同时,对__index的定义将会被忽略。

    就这么简单。假如你已经有现成的类,而你没有修改该类的权力,如何将其加入到Lua中呢?答案就是,继承它,将把派生类加入到Lua中。

结束语
  LuaWrapper 需要用到boost库的支持:boost/type_traits.hpp, boost/function.hpp, boost/bind.hpp,它使用了C++的模板部份特化,因此,C++编译器如果不支持此特性,将无法编译。目前支持此特性的编译器已经有很多。在VisualStudo产品系列中,只有VC7.1能支持此特性,因此,您如果正在使用VisualStudio,请确认你用的是VisualStudio2003。
  如果你觉得 LuaWrapper For C++ 能够帮助你,我会感觉很荣幸。我很愿意将这个程序库分享给大家。顺便一提的是,如果你在使用过程中发现BUG,或是有好的建议,希望您能与我联系。你在使用过程中,请不要删除文件中的署名信息;如果你修改了程序库,请您在修改的文件中加入您的修改说明。当然,我会非常欢迎您能将修改后的程序回馈给我。我会继续优化并完善它。

=============================================================

File: Click Here Download: LuaWrapper For C++
File: Click Here Download: LuaWrapper test program

=============================================================

  1. 很久以前,那还是我用win98的时候有次我系统崩溃了,因为我是电脑白吃,我朋友给我介绍了一个高手来帮我修电脑。

他看了一下电脑,问我有没有98的盘,我说没有。

注意力的集中作为一种特殊的素质和能力,需要通过训练来获得。那么,训练自己注意力、提高自己专心致志素质的方法有哪些呢?  

方法之一:运用积极目标的力量  

         这种方法的含义是什么?就是当你给自己设定了一个要自觉提高自己注意力和专心能力的目标时,你就会发现,你在非常短的时间内,集中注意力这种能力有了迅速的发展和变化。  

         同学们要在训练中完成这个进步。要有一个目标,就是从现在开始我比过去善于集中注意力。不论做任何事情,一旦进入,能够迅速地不受干扰。这是非常重要的。比如,你今天如果对自己有这个要求,我要在高度注意力集中的情况下,将这一讲的内容基本上一次都记忆下来。当你有了这样一个训练目标时,你的注意力本身就会高度集中,你就会排除干扰。  

         同学们知道,在军事上把兵力漫无目的地分散开,被敌人各个围歼,是败军之将。这与我们在学习、工作和事业中一样,将自己的精力漫无目标地散漫一片,永远是一个失败的人物。学会在需要的任何时候将自己的力量集中起来,注意力集中起来,这是一个成功者的天才品质。培养这种品质的第一个方法,是要有这样的目标。  

方法之二:培养对专心素质的兴趣  

         有了这种兴趣,你们就会给自己设置很多训练的科目,训练的方式,训练的手段。你们就会在很短的时间内,甚至完全有可能通过一个暑期的自我训练,发现自己和书上所赞扬的那些大科学家、大思想家、大文学家、大政治家、大军事家一样,有了令人称赞的注意力集中的能力。  

         同学们在休息和玩耍中可以散漫自在,一旦开始做一件事情,如何迅速集中自己的注意力,这是一个才能。就像一个军事家迅速集中自己的兵力,在一个点上歼灭敌人,这是军事天才。我们知道,在军事上,要集中自己的兵力而不被敌人觉察,要战胜各种空间、地理、时间的困难,要战胜军队的疲劳状态,要调动方方面面的因素,需要各种集中兵力的具体手段。同学们集中自己的精力,注意力,也要掌握各种各样的手段。这些都值得探讨,是很有兴趣的事情。  

方法之三:要有对专心素质的自信  

         千万不要受自己和他人的不良暗示。有的家长从小就这样说孩子:我的孩子注意力不集中。在很多场合都听到家长说:我的孩子上课时精力不集中。有的同学自己可能也这样认为。不要这样认为,因为这种状态可以改变。  

         如果你现在比较善于集中注意力,那么,肯定那些天才的科学家、思想家、事业家、艺术家在这方面还有值得你学习的地方,你还有不及他们的差距,你就要想办法超过他们。  

         对于绝大多数同学,只要你有这个自信心,相信自己可以具备迅速提高注意力集中的能力,能够掌握专心这样一种方法,你就能具备这种素质。我们都是正常人、健康人,只要我们下定决心,不受干扰,排除干扰,我们肯定可以做到高度的注意力集中。希望同学们对自己实行训练。经过这样的训练,能够发生一个飞跃。  

方法之四:善于排除外界干扰  

         要在排除干扰中训练排除干扰的能力。毛泽东在年轻的时候为了训练自己注意力集中的能力,曾经给自己立下这样一个训练科目,到城门洞里、车水马龙之处读书。为了什么?就是为了训练自己的抗干扰能力。同学们一定知道,一些优秀的军事家在炮火连天的情况下,依然能够非常沉静地、注意力高度集中地在指挥中心判断战略战术的选择和取向。生死的危险就悬在头上,可是还要能够排除这种威胁对你的干扰,来判断军事上如何部署。这种抗拒环境干扰的能力,需要训练。  

         我在你们这么大的年纪时曾有意做过这种训练。就是不管环境多么嘈杂,当我进入我要阅读和学习的科目时,对周围的一切因素置若罔闻。这是可以训练成功的。  

方法之五:善于排除内心的干扰  

         在这里要排除的不是环境的干扰,而是内心的干扰。环境可能很安静,在课堂上,周围的同学都坐得很好,但是,自己内心可能有一种骚动,有一种干扰自己的情绪活动,有一种与这个学习不相关的兴奋。对各种各样的情绪活动,要善于将它们放下来,予以排除。这时候,同学们要学会将自己的身体坐端正,将身体放松下来,将整个面部表情放松下来,也就是将内心各种情绪的干扰随同这个身体的放松都放到一边。常常内心的干扰比环境的干扰更严重。