Heath's Blog

There is no end, it is just the beginning! - A Game Developer's Notes

Some tips of using toLua

在使用toLua重构脚本系统时,遇到了一些问题,在此将其解决方案做一下备忘。

一、How to complie
    在linux下只需简单地执行make即可。而在windows平台下,情况会稍微复杂点。由于toLua的产出分为exe和lib,其中exe用于自动产生bind代码,lib作为脚本系统的连接库使用。为了产生exe文件,需要创建一个win32 console工程,将src\lib和src\bin的.h、.c添加到这个工程中来,然后编译(当然别忘了设置链接lua库);而产生lib,则需要创建static lib工程,然后将src\lib下的source添加进来编译(同样别忘了设置链接lua库)。
二、How to use(How to transplant)
    在src\tests下有示例代码,其中.pkg文件内容与header file几乎一致,只是多了toLua处理指令(以$开头),其详细说明可参考“tolua++ - Reference Manual”。为了避免将众多的header files内容复制到.pkg,我们使用了$cfile指令,这样只需在每个需要导出到lua中的头文件所对应的.pkg文件中添加一条$cfile指令即可,但世上没有免费的午餐,这样做有个前提:需要在头文件中添加导出指示符(以注释方式给出)。需要注意的是:1).pkg文件必须以一个新行结束文件;2)使用导出指示符时,//tolua_export需位于类名继承关系之后。对于导出单个或少数方法,需要在方法声明前加//tolua_begin,结束加//tolua_end。对于如果//tolua_end不在类定义最后(即};之后)的情况,需在类定义最后加//tolua_export;3)如需在脚本中生成对象,则需导出构造和析构函数。下面举具体例子加以说明:

//////////Test.h/////////////
#pragma once

class Hello 
{
public:
    Hello();
    
virtual ~Hello();
    
virtual void Say();
}
;

class HelloWorld : public Hello {//tolua_export
public:
    
//tolua_begin
    HelloWorld() {}
    
~HelloWorld() {}
    
//tolua_end
    void Say();
    
//tolua_begin
    void GG();
    
//tolua_end
}
;//tolua_export

/////////////Test.cpp////////////////

#include 
"Test.h"
#include 
<iostream>

using namespace std;

Hello::Hello()
{

}


Hello::
~Hello()
{

}


void Hello::Say()
{
    cout 
<< "Hello" << endl;
}


void HelloWorld::Say()
{
    cout 
<< "Hello, World!" << endl;
}


void HelloWorld::GG()
{
    cout 
<< "Go go!" << endl;
}

////////main.cpp////////

include 
"toLua.h"
#include 
"_Test.h"  /// generate by toLua

void main()
{
    
int tolua_Test_open(lua_State*);

    lua_State
* L = lua_open();
    luaL_openlibs(L);
    tolua_Test_open(L);

    luaL_dofile(L , 
"Test.Lua");

    lua_close(L);
}

//////////Test.lua/////////
print "Start"
local hw 
= HelloWorld:new()
hw:GG()
print "End"

//////Test.pkg//////
$cfile 
"Test.h"
<new line>


_Test.h和_Test.cpp是用ToLua -o _Test.cpp -H _Test.h Test.pkg命令产生的。


补充:针对在脚本中使用已经创建好的C++对象,需要使用tolua_pushusertype和lua_setglobal。在上面例子中,如果只想在脚本中调用指定对象的GG方法,则只需用tolua_begin和tolua_end来包括GG(),然后修改main.cpp和脚本:

///////main.cpp//////

#include 
"toLua.h"
#include 
"_Test.h"

void main()
{
    
int tolua_Test_open(lua_State*);

    lua_State
* L = lua_open();
    luaL_openlibs(L);
    tolua_Test_open(L);
    HelloWorld
* pHelloWorld = new HelloWorld;
    tolua_pushusertype(L,(
void*)pHelloWorld,"HelloWorld");
    lua_setglobal(L , 
"HelloWorld");
    luaL_dofile(L , 
"Test.Lua");

    lua_close(L);
}

 

////////Test.lua////////

print 
"Start"
HelloWorld:GG()
print 
"End"


三、How to automatize

    Visual studio为每个工程提供了配置“Pre-Build Event”、“Pre-Link Event”以及“Post-Build Event”的机会,她位于工程属性的“Build Events”条目中。为了在每次编译前,自动产生lua绑定的相关代码,可在“Command Line”中写下我们在命令行中输入的toLua命令。

posted on 2009-01-18 13:56 Heath 阅读(2060) 评论(2)  编辑 收藏 引用 所属分类: Script Programming

Feedback

# re: Some tips of using toLua[未登录] 2009-01-21 19:25 ME

這媞什庅語誩?  回复  更多评论   

# re: Some tips of using toLua 2009-06-16 14:53 lion

@ME
火星文
  回复  更多评论   


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理