posts - 311, comments - 0, trackbacks - 0, articles - 0
  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理
原文地址: http://www.codenix.com/~tolua/tolua++.html

译者注:在网上貌似没有对应的tolua中文版文档,故心血来潮,翻译了第一部分:tolua使用。第一次翻译,出了很多错误。可能还潜在很多的错误,建议和原版一起阅读。如果有错误,希望各位看官指出,谢谢。



Tolua++tolua的升级版,是把C/C++lua代码结合使用的一种工具。tolua++包括一些来自C++的新功能,如:

  • 支持std::string,并将其作为一种基本类型
  • 支持class template

当然,还有一些新的特点和bug的修复。

Tolua的使用大大简化了C/C++和lua的代码一体化。基于干净的头文件(或者扩展的头文件),tolua会自动生成相关的代码供lua访问C/C++使用。

使用Lua的API和标记方法(tag method facilities),tolua可以把C/C++里的常数,变量,函数,类和方法映射到lua。

这本手册是tolua++ 1.0版本,针对Lua5.0以上,基于tolua5.0。如果使用旧版本,请查看兼容性的详细资料。

以下各节描述如何使用tolua 。如果你发现错误,或者有建议和意见,请与我们联系。

How tolua works

要使用tolua,我们需要创建package文件,C/C++干净的头文件(cleaned header file),只列出所有我们希望暴露给lua使用的常数,变量,函数,类和方法。然后tolua剖析这个文件,并自动创建C / C + +文件,该文件会自动把C/C++的代码绑定到Lua。当我们的程序链接到这个文件时,我们就能从Lua访问对应的C/C++代码。

Package文件可以包括常规头文件,其他Package文件,以及lua文件。

让我们先以一些例子。如果我们指定下列C头文件输入到tolua:

 #define FALSE 0
 #define TRUE 1
 
 enum { 
  POINT = 100, 
  LINE, 
  POLYGON
 }
 Object* createObejct (int type);
 void drawObject (Object* obj, double red, double green, double blue);
 int isSelected (Object* obj);

这段代码绑定到Lua,会自动生成一个C文件。因此,在Lua代码里,我们能够访问对应的C代码,例如(writing, for instance:):

...
myLine = createObject(LINE)
...
if isSelected(myLine) == TRUE then
   rawObject(myLine, 1.0, 0.0, 0.0);
else
   rawObject(myLine, 1.0, 1.0, 1.0);
end
...

另外,考虑一个C++头文件:

 #define FALSE 0
#define TRUE 1
class Shape
 {
   void draw (void);
   void draw (double red, double green, double blue);
   int isSelected (void);
 };
 class Line : public Shape
 {
  Line (double x1, double y1, double x2, double y2);
  ~Line (void);
 };
 

如果这个文件是用来加载到tolua的,一个C++文件会自动生成,为Lua提供访问对应代码。因此,以下的Lua代码是有效的:

 ...
 myLine = Line:new (0,0,1,1)
 ...
 if myLine:isSelected() == TRUE then
  myLine:draw(1.0,0.0,0.0)
 else
  myLine:draw()
 end
 ...
 myLine:delete()
 ...

Package文件传给tolua的不是真正的C/C++头文件,而是一种干净的版本(cleaned version)。Tolua并不执行一个完整的剖析解释的C/C++代码,只是解析一些声明,用来描述暴露给lua功能的声明(it understands a few declarations that are used to describe the features that are to be exported to Lua.)。

通常头文件可以包括进packages文件里,tolua会提取对应的代码用于解析对应的头文件(see Basic Concepts).

How to use toLua

Tolua由两部分代码组成:可执行程序和静态库(an executable and a library)。可执行程序用于解析,从package文件读入,然后输出C/C++代码,该代码为lua提供访问C/C++的方法。如果package文件是与C++类似的代码(例如包括类的定义),就会生成一份C++代码。如果package文件是与C类似的代码(例如不包括类),就会生成一份C代码。Tolua接收一系列选择(tolua accepts a set of options)。运行“tolua -h”显示当前可接收的选择。例如,要解析一个名为myfile.pkg生成一个名为myfile.c的捆绑代码,我们需要输入:

tolua -o myfile.c myfile.pkg

产生的代码必须被应用程序生成和链接,才能提供给Lua进行访问。每个被解析的文件会生成一个package暴露给Lua。默认情况下,软件包的名称是根输入文件名称( myfile的例子),用户可以指定一个不同的名称给package

tolua -n pkgname -o myfile.c myfile.pkg

package还应当明确初始化。我们需要声明和调用初始化函数,从化我们的C/C++代码初始化package。初始化函数被定义为:

int tolua_pkgname_open (lua_State*);

其中pkgname是被绑定package的名字。如果我们使用的是C++,我们可以选择自动初始化:

tolua -a -n pkgname -o myfile.c myfile.pkg

在这种情况下,初始化函数会自动调用。然而,如果我们计划使用多个Lua,自动初始化就行不通了,因为静态变量初始化的顺序在C++里没有定义。

Optionally, the prototype of the open function can be outputted to a header file, which name is given by the -H option.

Tolua生成的绑定代码使用了一系列tolua库里面的函数。因此,这个库同样需要被链接到应用程序中。同样,tolua.h需要加入编译生成代码。应用程序无需绑定任何package文件也可以使用tolua的面向对象框架(see exported utility functions)。在这种情况下,应用程序必须调用tolua初始化函数(此函数被称为任何package文件初始化功能)

int tolua_open (void);

Basic Concepts

第一步是使用tolua创建package文件。从真正的头文件开始,我们重新将想要暴露给lua的特性转换成tolua可以理解的格式。

Including files

一个package文件可以包括其他的package文件。一般的格式是:

$pfile "include_file"

一个package文件同样可以包括一般的C/C++头文件,使用hfilecfile指令:

$cfile "example.h"

在这种情况下, tolua将提取的代码封闭之间tolua_begintolua_end ,或tolua_export的一条直线上。以这个C++头为例思考:(注:这里并不是每个头文件都需要使用这些注释来告诉tolua要加入这些代码,仅仅是对于package文件包括的头文件而言)

 
#ifndef EXAMPLE_H
#define EXAMPLE_H
 
class Example { // tolua_export
 
private:
 
 string name;
 int number;
 
public:
 
 void set_number(int number);
 
 //tolua_begin
 
 string get_name();
 int get_number();
};
// tolua_end
 
#endif

In this case, the code that's not supported by tolua (the private part of the class), along with the function set_number is left outside of the package that includes this header.

最后,lua文件可以被包括在package文件里,使用$lfile:

$lfile "example.lua"

新的tolua++:自1.0.4版本以来的tolua++,提供了一个额外的方式可以包括源文件,使用ifile:

$ifile "filename"

ifile还额外的可选参数后的文件名(ifile also takes extra optional parameters after the filename),例如:

$ifile "widget.h", GUI
$ifile "vector.h", math, 3d

ifile的默认行为是包括整个文件的原样。但是,该文件的内容和额外的参数在被纳入package之前通过include_file_hook函数进行处理 (see Customizing tolua++ for more details)