??xml version="1.0" encoding="utf-8" standalone="yes"?>欧美喷潮久久久XXXXx,色欲久久久天天天综合网,久久精品嫩草影院http://www.shnenglu.com/colorful/category/19902.htmlzc qq:1337220912zh-cnMon, 02 Mar 2015 22:16:29 GMTMon, 02 Mar 2015 22:16:29 GMT60qcjl lua project loghttp://www.shnenglu.com/colorful/archive/2015/03/01/209893.html多彩人生多彩人生Sun, 01 Mar 2015 03:55:00 GMThttp://www.shnenglu.com/colorful/archive/2015/03/01/209893.htmlhttp://www.shnenglu.com/colorful/comments/209893.htmlhttp://www.shnenglu.com/colorful/archive/2015/03/01/209893.html#Feedback0http://www.shnenglu.com/colorful/comments/commentRss/209893.htmlhttp://www.shnenglu.com/colorful/services/trackbacks/209893.htmlprotoc-gen-lua 生成的lua又发现新的问? main function has more than 200 local variables问题Q网上搜索了一下,有相应的解决ҎQ据说还会有一个新的问题出来:不能?repeated submessage,  用云风的pbc. 所以方案改为用云风的pbc

多彩人生 2015-03-01 11:55 发表评论
]]>
cocos2dx lua protobufhttp://www.shnenglu.com/colorful/archive/2015/02/12/209802.html多彩人生多彩人生Thu, 12 Feb 2015 03:42:00 GMThttp://www.shnenglu.com/colorful/archive/2015/02/12/209802.htmlhttp://www.shnenglu.com/colorful/comments/209802.htmlhttp://www.shnenglu.com/colorful/archive/2015/02/12/209802.html#Feedback0http://www.shnenglu.com/colorful/comments/commentRss/209802.htmlhttp://www.shnenglu.com/colorful/services/trackbacks/209802.html
http://blog.csdn.net/weyson/article/details/17024325
http://www.shnenglu.com/colorful/archive/2015/01/17/209557.html
http://blog.csdn.net/w00w12l/article/details/39316321

protoc-gen-lua下蝲地址: https://github.com/sean-lin/protoc-gen-lua

1/ 先到protobuf的python目录下执?br />    python setup.py build
    python setup.py install

2/ 在protoc-gen-lua的plugin目录中新建protoc-gen-lua.bat, 内容如下:
@python 目录\protoc-gen-lua\plugin\protoc-gen-lua

3/ 用protoc把proto文g生成lua文g
  protoc --lua_out=./ --plugin=protoc-gen-lua="目录\protoc-gen-lua.bat"  test.proto

4/ protoc-gen-lua/protobuf下的pb.c 攑ֈ工程的Classes? q加入到c++工程?br />
5/ protoc-gen-lua/protobuf上的所有lua文g攑ֈ工程的src目录(lua目录)?br />
6/ AppDelegate.cpp d代码
extern "C"{
    int luaopen_pb(lua_State* L);
}
在applicationDidFinishLaunching()中调?luaopen_pb(state);

---------------------------------------------------------------------------
    require "src/xy/person_pb"  
    local msg = person_pb.Person()  
    msg.id = 100   
    msg.name = "foo"   
    msg.email = "bar"   

    local pb_data = msg:SerializeToString()  -- Parse Example  
    print("create:", msg.id, msg.name, msg.email, pb_data)  


    local msg = person_pb.Person()   
    msg:ParseFromString(pb_data)   
    print("parser:", msg.id, msg.name, msg.email, pb_data)

---------------------------------------------------------------------------
UL到android 记得pb.cd到proj.android\jni\Android.mk?br />
 

多彩人生 2015-02-12 11:42 发表评论
]]>
Quick-Cocos2d-x 集成 Google protobuf Ҏhttp://www.shnenglu.com/colorful/archive/2015/01/17/209557.html多彩人生多彩人生Sat, 17 Jan 2015 08:08:00 GMThttp://www.shnenglu.com/colorful/archive/2015/01/17/209557.htmlhttp://www.shnenglu.com/colorful/comments/209557.htmlhttp://www.shnenglu.com/colorful/archive/2015/01/17/209557.html#Feedback0http://www.shnenglu.com/colorful/comments/commentRss/209557.htmlhttp://www.shnenglu.com/colorful/services/trackbacks/209557.htmlhttp://cn.cocos2d-x.org/tutorial/show?id=506
本文向您介lQuick-Cocos2d-x集成google protobuf的方法? 
 
W一?  需要最新的protobuf cd和解析程序?nbsp;
下蝲地址Q?a target="_blank">https://github.com/sean-lin/protoc-gen-lua
 
git clone https://github.com/sean-lin/protoc-gen-lua.git CQ意的一个地?
 

然后Q可以得到重要的两个目录

1
2
protoc-gen-lua/plugin/ 
protoc-gen-lua/protobuf/
 
W二步, 需要用protoc —lua_out=. q种ҎQ?我们自q*.proto 的文件解析成lua文g

plugin目录是提供将buffer 文g解析成lua 版本的类库, 需要python 支持? 如果已经~译了google 官方的protoc 那个E序Q?只需要在pȝPATH环境变量总追加plugin目录好:

1
export PATH={protoc-gen-lua DIR }/plugin:$PATH
 
关于protoc的编译另请google .
 
如果解析不出lua文g来, 可以手动志信一下plugin/protoc-gen-lua的程序, 他应该是+x 的权?chmod +x plugin/protoc-gen-lua)
 
l节的安装步骤可以参?nbsp;https://code.google.com/p/protoc-gen-lua/
 
W三?Q?protobuf 集成到quick ?/strong>
protoc-gen-lua/protobuf/ 目录是要编译到quick-cocos2d-x目录里面的部分?nbsp;
 
现在Q?我们只需?protoc-gen-lua/protobuf/pb.c q个文g 
 

先确定自qquick-cocos2d-x lua扩展目录Q?

1
/quick-cocos2d-x/lib/cocos2d-x/scripting/lua/lua_extensions/
 
所有lua 的c/c++现成扩展,都可以直接放到这里?nbsp;
  
pb.cq个文g复制?lua_extension目录下, 最好独立一个目录, 免得扩展多了乱?nbsp;
  

q是我的目录l构:

1
./quick-cocos2d-x/lib/cocos2d-x/scripting/lua/lua_extensions/protobuf/pb.c
  
然后开始修Ҏ展程序配|文? lua_extensions.c
 

路径为:

1
./quick-cocos2d-x/lib/cocos2d-x/scripting/lua/lua_extensions/lua_extensions.c
 

目前是一个不?0行的文Ӟ 我打全部脓q来Q?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#include "lua_extensions.h" 
   
#if __cplusplus 
extern "C"
#endif 
    
// cjson 
#include "cjson/lua_cjson.h" 
    
    
// zlib 
#include "zlib/lua_zlib.h" 
    
    
// lpack 
#include "lpack/lpack.h" 
    
    
// socket 
#include "socket/luasocket.h" 
#include "socket/mime.h" 
#include "socket/socket_scripts.h" 
    
    
// filesystem 
#include "filesystem/lfs.h" 
    
    
// lsqlite3 
#include "lsqlite3/lsqlite3.h" 
    
    
#include "protobuf/pb.c"   //引用protobuf 库文?nbsp;
    
    
static luaL_Reg luax_exts[] = { 
     {"cjson", luaopen_cjson_safe}, 
     {"zlib", luaopen_zlib}, 
     {"pack", luaopen_pack}, 
     {"socket.core", luaopen_socket_core}, 
     {"mime.core", luaopen_mime_core}, 
     {"lfs", luaopen_lfs}, 
     {"lsqlite3", luaopen_lsqlite3}, 
     {NULL, NULL} 
}; 
    
    
void luaopen_lua_extensions(lua_State *L) 
     // load extensions 
     luaL_Reg* lib = luax_exts; 
     lua_getglobal(L, "package"); 
     lua_getfield(L, -1, "preload"); 
     for (; lib->func; lib++) 
     
         lua_pushcfunction(L, lib->func); 
         lua_setfield(L, -2, lib->name); 
     
     lua_pop(L, 2); 
    
    
     // load extensions script 
     luaopen_socket_scripts(L); 
     luaopen_pb(L);   //q是加入的protobuf 扩展注册?nbsp;
    
    
#if __cplusplus 
} // extern "C" 
#endif
x Q?protobuf 扩展部分q扩展完成了?nbsp;
 
认是否成功支持 Q?可以在quick 目最先被调用的lua文g中追?require "pb" 做测试?nbsp;
 
*但这时候通过protoc 转码后得到的lua文gq不能被解析?nbsp;
 
W四?从项目中包含protobuf?lua?/strong>
protoc-gen-lua/protobuf/q个目录下面Q?q有大量?lua文gQ?是用来支持proto转码后的文g解析调用的?不能了q些文g?nbsp;
 
复制protoc-gen-lua/protobuf文g?到项目中 scripts目录下? 
  

目录l构应该是这LQ?

1
[PROJECT]/scripts/protobuf/*.lua
 
然后Q?需要告诉框Ӟ从哪里可以引用到它?nbsp;
 

修改main.lua 在require("appxxxxxx") 上面 Q?加入下面的代码:

1
package.path = package.path .. ";./protobuf/?.lua;./scripts/protobuf/?.lua;"
 
q个ҎQ?能保证程序在被编译到手机之后仍然可以l箋讉Kq个库?nbsp;
  
***千万别把转码的proto文g攑ֈ[PROJECT]/scripts/protobuf 目录里面.不信可以试试?
 
现在Q?目支持protobuf 文g的解析了?
 
W五? 重新~译player-x
如果不习惯用player-x调试Q?q个步骤不是必须的?nbsp;
 

q入player-x qt源码目录 Q?

1
cd quick-cocos2d-x/player/proj.qt
 

使用qmake 文g执行quick-x.pro 文g 

1
qmake ./quick-x.pro
 
l箋Q?
make 
 
{待l束Q?得到的quick-x-player文gQ?nbsp;
 
攑ֈQquick-cocos2d-x/player/bin/mac/ 目录下, q样sublime text 装QuickXDev 扩展的直接可以用?nbsp;
  
**如果是mac os 10.9 pȝQ?可能~译不过去player-xE序?我遇Cq个问题?nbsp;
 
会提C错? pb.c:28:10: fatal error: 'endian.h' file not found 
 

如果错误信息相同Q?修改文g:

1
./quick-cocos2d-x/lib/cocos2d-x/scripting/lua/lua_extensions/protobuf/pb.c
 

查找?

1
#include <endian.h>
  

临时变更为:

1
#include <machine/endian.h>
  
然后重新~译 player-x 
 
make p够了 
 
make
 
**player-x ~译完毕后, 千万要将endian.h 引用改回原来?#include <endian.h> Q?否则打包到手机的时候又回提C文件找不到了?nbsp;


多彩人生 2015-01-17 16:08 发表评论
]]>
Lua注册回调到C++http://www.shnenglu.com/colorful/archive/2015/01/17/209553.html多彩人生多彩人生Sat, 17 Jan 2015 03:12:00 GMThttp://www.shnenglu.com/colorful/archive/2015/01/17/209553.htmlhttp://www.shnenglu.com/colorful/comments/209553.htmlhttp://www.shnenglu.com/colorful/archive/2015/01/17/209553.html#Feedback0http://www.shnenglu.com/colorful/comments/commentRss/209553.htmlhttp://www.shnenglu.com/colorful/services/trackbacks/209553.htmlhttp://cn.cocos2d-x.org/tutorial/show?id=1896

思\

像所有语a一Pl定回调主要是执行的d执行到特定情形的时候,调用对用回调Ҏ?本文也一PLua注册回调到C++的核心思\是,当C代码执行到特定特定情形的时候,调用Lua的方法?/p>

我这里用的是用lua_stack直接调用lua的方法,没有使用Cocos2d-x装的那个dispatcherQ因为熟悉那个格式太墨迹了?/p>


主要步骤如下

  • ~存Lua函数在Lua环境中的引用

  • 在C代码的地方用C的方式设|好回调

  • 在C代码回调函数执行的时候,调用lua函数


实现

  • C代码l定回调Q调用Lua函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
void ArmatureNode::registerMovementEventHandler(int handler)
{
    unregisterMovementEventHandler();  //U除之前注册的监?/code>
    _movementHandler = handler;         //~存lua函数的引?nbsp;q个后边?/code>
     
    auto dispatcher = getCCEventDispatcher();
     
    auto f = [this](cocos2d::EventCustom *event) //注册c代码形式的回?nbsp;q里用function?/code>
    {
        auto eventData = (dragonBones::EventData*)(event->getUserData());
        auto type = (int) eventData->getType();
        auto movementId = eventData->animationState->name;
        auto lastState = eventData->armature->getAnimation()->getLastAnimationState();
         
        auto stack = cocos2d::LuaEngine::getInstance()->getLuaStack();
        stack->pushObject(this"db.ArmatureNode");
        stack->pushInt(type);
        stack->pushString(movementId.c_str(), movementId.size());        
        //通过LuaStack调用lua里的函数    最后一个参数设|参C?/code>
        stack->executeFunctionByHandler(_movementHandler, 3);
    };
     
    dispatcher->addCustomEventListener(dragonBones::EventData::COMPLETE, f);
}
void ArmatureNode::unregisterMovementEventHandler(void)
{
    if (0 != _movementHandler)
    {
        cocos2d::LuaEngine::getInstance()->removeScriptHandler(_movementHandler); //U除lua函数的绑?/code>
        _movementHandler = 0;
    }
}
  • 提供Lua函数l定到C的方?  

上边的这个函数直接用cocos里的genbinding.py 是无法正生成Lua里可调用的接口的Q需要手动编写绑定方?

说这个得用到Cocos2d-x中提供的一个方法:toluafix_ref_function会把一个Lua栈中的方法{成一个intQ以便C++中调用。我会在最后面说这?/p>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
int tolua_db_DBCCArmature_registerMovementEventHandler(lua_State* tolua_S)
{
    if (NULL == tolua_S)
        return 0;
    int argc = 0;
     
    dragonBones::ArmatureNode* self = nullptr;
    self = static_cast<dragonBones::ArmatureNode*>(tolua_tousertype(tolua_S,1,0)); //W一个参?nbsp;是lua里的self
     
    argc = lua_gettop(tolua_S) - 1;
     
    if (1 == argc)
    {
        //W二个参敎ͼ是Lua里的function q里要通过toluafix_ref_functionq个函数映射成一个Int?/code>
        int handler = (toluafix_ref_function(tolua_S,2,0)); 
        self->registerMovementEventHandler(handler);
         
        return 0;
    }
    return 0;
}

 

  • 绑定方法绑定到Lua环境?/p>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
int extends_ArmatureNode(lua_State* tolua_S)
{
    lua_pushstring(tolua_S, "db.ArmatureNode");//之前db.ArmatureNode是通过脚本l定在lua里。这里只做扩?/code>
    lua_rawget(tolua_S, LUA_REGISTRYINDEX);
    if (lua_istable(tolua_S,-1))
    {
        lua_pushstring(tolua_S,"registerMovementEventHandler");
        lua_pushcfunction(tolua_S,tolua_db_DBCCArmature_registerMovementEventHandler);
        lua_rawset(tolua_S,-3);
    }
     
    lua_pop(tolua_S, 1);
    return 0;
}
  • Lua里设|回调到C++

1
2
3
4
5
6
7
8
 local arm = db.ArmatureNode:create("Dragon")
    local animation = arm:getAnimation()
    animation:gotoAndPlay("walk")
    arm:registerMovementEventHandler(
        function(...)
            print(...) 
        end
    )


-试

打印回调输出Q测试通过 userdata 8 walk


其他

  • toluafix_ref_function 以及 toluafix_get_function_by_refid

q?两个Ҏ是相互对应的 toluafix_ref_functionq个Ҏ在注册表上将一个lua的function与一个function_id生成映射 toluafix_get_function_by_refid Ҏ可以通过前一个方法生成的function_id来讲l定的lua function攑ֈ栈顶

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//
TOLUA_API int toluafix_ref_function(lua_State* L, int lo, int def)
{
    if (!lua_isfunction(L, lo)) return 0;
    s_function_ref_id++;                            //function_id ?
    lua_pushstring(L, TOLUA_REFID_FUNCTION_MAPPING);//在注册表上,存放luafunction 映射table 的key压栈
    lua_rawget(L, LUA_REGISTRYINDEX);               //获取Ҏ映射表,攑֜栈顶
    lua_pushinteger(L, s_function_ref_id);          //function_id压栈
    lua_pushvalue(L, lo);                           //lo有效处烦引处是luaҎQluaҎ拯Q压?/code>
 
 
    lua_rawset(L, -3);                        //生成映射 
    lua_pop(L, 1);                                              
    return s_function_ref_id;
}
TOLUA_API void toluafix_get_function_by_refid(lua_State* L, int refid)
{
    lua_pushstring(L, TOLUA_REFID_FUNCTION_MAPPING);            //存放luafunction 映射table 的key压栈
    lua_rawget(L, LUA_REGISTRYINDEX);                           //获取Ҏ映射表,攑֜栈顶
    lua_pushinteger(L, refid);                                  //function_id压栈
    lua_rawget(L, -2);                                          //获取到的luafunction 攑ֈ栈顶
    lua_remove(L, -2);                                          //
}
  • executeFunctionByHandler

executeFunctionByHandler q个Ҏ只是通过toluafix_get_function_by_refid 获取到function然后通过lua_pcall Ҏ调用Q代码就不写了?/p>



多彩人生 2015-01-17 11:12 发表评论
]]>
lua意见http://www.shnenglu.com/colorful/archive/2015/01/13/209495.html多彩人生多彩人生Tue, 13 Jan 2015 02:54:00 GMThttp://www.shnenglu.com/colorful/archive/2015/01/13/209495.htmlhttp://www.shnenglu.com/colorful/comments/209495.htmlhttp://www.shnenglu.com/colorful/archive/2015/01/13/209495.html#Feedback0http://www.shnenglu.com/colorful/comments/commentRss/209495.htmlhttp://www.shnenglu.com/colorful/services/trackbacks/209495.html

多彩人生 2015-01-13 10:54 发表评论
]]>
Lua的sleep函数http://www.shnenglu.com/colorful/archive/2015/01/01/209374.html多彩人生多彩人生Thu, 01 Jan 2015 08:59:00 GMThttp://www.shnenglu.com/colorful/archive/2015/01/01/209374.htmlhttp://www.shnenglu.com/colorful/comments/209374.htmlhttp://www.shnenglu.com/colorful/archive/2015/01/01/209374.html#Feedback0http://www.shnenglu.com/colorful/comments/commentRss/209374.htmlhttp://www.shnenglu.com/colorful/services/trackbacks/209374.html

一个不q的消息是Lua中没有内|sleep函数Q我们需要DIY。有4U方法可以实现sleep函数Q如下:

Ҏ1

--在一个死循环中设|一个蟩出条Ӟ但是q样的做法会占用大量CPU资源Q强烈不推荐使用?/p>

function sleep(n)

   local t0 = os.clock()

   while os.clock() - t0 <= n do end

Ҏ2

--调用pȝ的sleep函数Q不消耗CPUQ但是Windowspȝ中没有内|这个命令(如果你又安装Cygwin马的也行)。推荐在Linuxpȝ中用该Ҏ

function sleep(n)

   os.execute("sleep " .. n)

Ҏ3

--虽然Windows没有内置sleep命oQ但是我们可以稍微利用下ping命o的性质

function sleep(n)

   if n > 0 then os.execute("ping -n " .. tonumber(n + 1) .. " localhost > NUL") end

Ҏ4

--使用socket库中select函数Q可以传?.1lnQ得休眠的旉_ֺ辑ֈ毫秒U别?/p>

‍require("socket")

function sleep(n)

   socket.select(nil, nil, n)



多彩人生 2015-01-01 16:59 发表评论
]]>
一个很不错的lua教程http://www.shnenglu.com/colorful/archive/2014/12/19/209257.html多彩人生多彩人生Fri, 19 Dec 2014 11:12:00 GMThttp://www.shnenglu.com/colorful/archive/2014/12/19/209257.htmlhttp://www.shnenglu.com/colorful/comments/209257.htmlhttp://www.shnenglu.com/colorful/archive/2014/12/19/209257.html#Feedback0http://www.shnenglu.com/colorful/comments/commentRss/209257.htmlhttp://www.shnenglu.com/colorful/services/trackbacks/209257.htmlhttp://www.cnblogs.com/stephen-liu74/category/360139.html
  Lua可以调用C函数的能力将极大的提高Lua的可扩展性和可用性。对于有些和操作pȝ相关的功能,或者是Ҏ率要求较高的模块Q我们完全可以通过C函数 来实玎ͼ之后再通过Lua调用指定的C函数。对于那些可被Lua调用的C函数而言Q其接口必须遵@Lua要求的Ş式,?span style="color: #0000ff;">typedef int (*lua_CFunction)(lua_State* L)?单说明一下,该函数类型仅仅包含一个表CLua环境的指针作为其唯一的参敎ͼ实现者可以通过该指针进一步获取Lua代码中实际传入的参数。返回值是?型,表示该C函数返回给Lua代码的返回值数量,如果没有q回|则return 0卛_。需要说明的是,C函数无法直接真正的q回D回给Lua代码Q而是通过虚拟栈来传递Lua代码和C函数之间的调用参数和q回值的。这里我们将?l两ULua调用C函数的规则?br />    1. C函数作ؓ应用E序的一部分?/span>
复制代码
 1 #include <stdio.h>  2 #include <string.h>  3 #include <lua.hpp>  4 #include <lauxlib.h>  5 #include <lualib.h>  6   7 //待Lua调用的C注册函数?/span>  8 static int add2(lua_State* L)  9 { 10     //查栈中的参数是否合法Q?表示Lua调用时的W一个参?从左到右)Q依此类推?11     //如果Lua代码在调用时传递的参数不ؓnumberQ该函数报错ƈl止E序的执行?/span> 12     double op1 = luaL_checknumber(L,1); 13     double op2 = luaL_checknumber(L,2); 14     //函数的l果压入栈中。如果有多个q回|可以在这里多ơ压入栈中?/span> 15     lua_pushnumber(L,op1 + op2); 16     //q回值用于提CC函数的返回值数量,卛_入栈中的q回值数量?/span> 17     return 1; 18 } 19  20 //另一个待Lua调用的C注册函数?/span> 21 static int sub2(lua_State* L) 22 { 23     double op1 = luaL_checknumber(L,1); 24     double op2 = luaL_checknumber(L,2); 25     lua_pushnumber(L,op1 - op2); 26     return 1; 27 } 28  29 const char* testfunc = "print(add2(1.0,2.0)) print(sub2(20.1,19))"; 30  31 int main() 32 { 33     lua_State* L = luaL_newstate(); 34     luaL_openlibs(L); 35     //指定的函数注册为Lua的全局函数变量Q其中第一个字W串参数为Lua代码 36     //在调用C函数时用的全局函数名,W二个参Cؓ实际C函数的指针?/span> 37     lua_register(L, "add2", add2); 38     lua_register(L, "sub2", sub2); 39     //在注册完所有的C函数之后Q即可在Lua的代码块中用这些已l注册的C函数了?/span> 40     if (luaL_dostring(L,testfunc)) 41         printf("Failed to invoke.\n"); 42     lua_close(L); 43     return 0; 44 }
复制代码

    2. C函数库成为Lua的模块?/span>
    包含C函数的代码生成库文gQ如Linux的soQ或Windows的DLLQ同时拷贝到Lua代码所在的当前目录Q或者是LUA_CPATH环境?量所指向的目录,以便于Lua解析器可以正定位到他们。在我当前的Windowspȝ中,我将其copy?C:\Program Files\Lua\5.1\clibs\"Q这里包含了所有Lua可调用的C库。见如下C语言代码和关键性注释:

复制代码
 1 #include <stdio.h>  2 #include <string.h>  3 #include <lua.hpp>  4 #include <lauxlib.h>  5 #include <lualib.h>  6   7 //待注册的C函数Q该函数的声明Ş式在上面的例子中已经l出? 8 //需要说明的是,该函数必MC的Ş式被导出Q因此extern "C"是必ȝ? 9 //函数代码和上例相同,q里不再赘述?/span> 10 extern "C" int add(lua_State* L)  11 { 12     double op1 = luaL_checknumber(L,1); 13     double op2 = luaL_checknumber(L,2); 14     lua_pushnumber(L,op1 + op2); 15     return 1; 16 } 17  18 extern "C" int sub(lua_State* L) 19 { 20     double op1 = luaL_checknumber(L,1); 21     double op2 = luaL_checknumber(L,2); 22     lua_pushnumber(L,op1 - op2); 23     return 1; 24 } 25  26 //luaL_Regl构体的W一个字Dؓ字符Ԍ在注册时用于通知Lua该函数的名字?27 //W一个字DؓC函数指针?28 //l构体数l中的最后一个元素的两个字段均ؓNULLQ用于提CLua注册函数已经到达数组的末?/span> 29 static luaL_Reg mylibs[] = {  30     {"add", add}, 31     {"sub", sub}, 32     {NULL, NULL}  33 };  34  35 //该C库的唯一入口函数。其函数{֐{同于上面的注册函数。见如下几点说明Q?36 //1. 我们可以该函数单的理解为模块的工厂函数?37 //2. 其函数名必须为luaopen_xxxQ其中xxx表示library名称。Lua代码require "xxx"需要与之对应?38 //3. 在luaL_register的调用中Q其W一个字W串参数为模块名"xxx"Q第二个参数为待注册函数的数l?39 //4. 需要强调的是,所有需要用?xxx"的代码,不论Cq是LuaQ都必须保持一_q是Lua的约定, 40 //   否则无法调用?/span> 41 extern "C" __declspec(dllexport) 42 int luaopen_mytestlib(lua_State* L)  43 { 44     const char* libName = "mytestlib"; 45     luaL_register(L,libName,mylibs); 46     return 1; 47 }
复制代码

    见如下Lua代码Q?/p>

1 require "mytestlib"  --指定包名U?/span> 2  3 --在调用时Q必Lpackage.function 4 print(mytestlib.add(1.0,2.0)) 5 print(mytestlib.sub(20.1,19))


多彩人生 2014-12-19 19:12 发表评论
]]>
用VS2010~译luabindhttp://www.shnenglu.com/colorful/archive/2014/09/02/208207.html多彩人生多彩人生Tue, 02 Sep 2014 09:56:00 GMThttp://www.shnenglu.com/colorful/archive/2014/09/02/208207.htmlhttp://www.shnenglu.com/colorful/comments/208207.htmlhttp://www.shnenglu.com/colorful/archive/2014/09/02/208207.html#Feedback0http://www.shnenglu.com/colorful/comments/commentRss/208207.htmlhttp://www.shnenglu.com/colorful/services/trackbacks/208207.htmlhttp://www.shnenglu.com/eros/archive/2009/04/29/81508.aspx

     学了一D|间LuaQ显然直接在目中用是很不方便Qgoogle了一下,g大家都对luabindq个lua包装c青睐有加,于是我也随大势想用用看?br />     先做好准备工作,下蝲了luabin 0.8.1源码QBoost 1.3.8源码和lua 5.1.4源码Q编译环境是VS2008 SP1。之前在|上看到一些文章说q些开源Y件之间的版本依赖比较敏感Q可能会有这样那L问题Q动手之前有些惶恐?br />     q运的是Q编译过E很利Q如下:
     1.~译lua 5.1.4
     q入VS2008的命令行工具Q定位到lua的源码目录下Q执行命令etc\luavs.batQ没什么问题的话很快就可以~译好luaQ得到lua51.lib和lua51.dll?br />     2.~译luabind
     解压下蝲回来的luabind压羃包,假设解压到d:\luabind-0.8.1\QBoost解压到d:\boost 1_38_0\Qlua解压到d:\lua 5.1.4\
     ?VS中新Z个静态库目Q将d:\luabind-0.8.1\src下的源码全部d到项目中Q然后在目中新建luabind和luabind \detail\两个虚拟文g夹,对应的将d:\luabind-0.8.1\luabind和d:\luabind-0.8.1\luabind \detail下的文gd到文件夹中?br />     然后为项目添加附加包含目录,右键点击目节点->属?>配置属?>C\C++标签下,在附加包含目录中填入d: \luabind-0.8.1\Qd:\boost 1_38_0\kQd:\lua 5.1.4\src\。然后修攚w目字W集为多字节字符集?br />     准备qAQ生成项目。在我的环境中编译很利Q没有出CQ何问题,成功后会得到luabind.lib?br />
     接下来就按照惯例来写一个hello worldE序作ؓ使用luabind的第一步?br />     在VS中新Z个控制台目Q类型ؓDLLQ命名项目ؓHello WorldQ然后键入以下代码:

 1#include "stdafx.h"
 2#include <iostream>
 3#include <luabind/luabind.hpp>
 4
 5void greet()
 6{
 7    std::cout << "hello world!\n";
 8}

 9
10extern "C" int __declspec(dllexport) init(lua_State* L)
11{
12    using namespace luabind;
13
14    open(L);
15
16    module(L)
17    [
18        def("greet"&greet)
19    ];
20
21    return 0;
22}


   注意Q在Windows环境下init函数之前是要?__declspec(dllexport)才能函数导出的Q而luabind的文档中的环境是linuxQ默认不用加 __declspec(dllexport)也可以导?因个折腾了我半天才把hello word成功q行)?br />   ~译目Q?记得luabind.lib和lua51.libd到链接选项中:目属?>q接?>输入->附加依赖文gQ加入luabind.lib和lua51.lib)?br />   hello world.dll攑ֈlua51.dll和lua.exe所在的目录下?br />   打开lua命o行,键入:
    
   试成功Qenjoy?/p>



多彩人生 2014-09-02 17:56 发表评论
]]>
析Lua中table的遍?http://www.shnenglu.com/colorful/archive/2014/08/25/208122.html多彩人生多彩人生Mon, 25 Aug 2014 06:29:00 GMThttp://www.shnenglu.com/colorful/archive/2014/08/25/208122.htmlhttp://www.shnenglu.com/colorful/comments/208122.htmlhttp://www.shnenglu.com/colorful/archive/2014/08/25/208122.html#Feedback0http://www.shnenglu.com/colorful/comments/commentRss/208122.htmlhttp://www.shnenglu.com/colorful/services/trackbacks/208122.htmlhttp://rangercyh.blog.51cto.com/1444712/1032925

当我在工作中使用luaq行开发时Q发现在lua中有4U方式遍历一个tableQ当Ӟ从本质上来说其实都一P只是形式不同Q这四种方式分别是:

  1. for key, value in pairs(tbtest) do  
  2. XXX  
  3. end 
  4.  
  5. for key, value in ipairs(tbtest) do  
  6. XXX  
  7. end 
  8.  
  9. for i=1, #(tbtest) do  
  10.     XXX  
  11. end 
  12.  
  13. for i=1, table.maxn(tbtest) do  
  14.     XXX  
  15. end 

前两U是泛型遍历Q后两种是数值型遍历。当然你q会说lua的table遍历q有很多U方法啊Q没错,不过最常见的这些遍历确实有必要弄清楚?/p>

q四U方式各有特点,׃在工作中我几乎每天都会用遍历table的方法,一开始也非常困惑q些方式的不同,一D|间后才渐渐明白,q里我也是把 自己的一点经验告诉大Ӟ对跟我一Llua初学者也许有些帮助(臛_当初我在写的时候在|上找了很久,不知道是因ؓ大牛们都认ؓq些很简单,不需?_q是因ؓ我笨Q连q都要问Q?/p>

首先要明一点,是lua中tableq像是C/C++中的数组一h序存储的,准确来说lua中的table更加像是C++中的mapQ?qKey对应存储ValueQ但是ƈ非顺序来保存key-value对,而是使用了hash的方式,q样能够更加快速的讉Kkey对应的valueQ我?也知道hash表的遍历需要用所谓的q代器来q行Q同Plua也有自己的P代器Q就是上?U遍历方式中的pairs和ipairs遍历。但是lua 同时提供了按照key来遍历的方式Q另外两U,实质上是一U)Q正式因为它提供了这U按key的遍历,才造成了我一开始的困惑Q我一度认为lua中关?table的遍历是按照我table定义key的顺序来的?/p>

下面依次来讲讲四U遍历方式,首先来看for k,v in pairs(tbtest) doq种方式Q?/p>

先看效果Q?/p>

  1. tbtest = {  
  2.     [1] = 1,  
  3.     [2] = 2,  
  4.     [3] = 3,  
  5.     [4] = 4,  
  6.  
  7. for key, value in pairs(tbtest) do  
  8.     print(value)  
  9. end 

我认出应该是1Q?Q?Q?Q实际上的输出是1Q?Q?Q?。我因ؓq个造成了一个bugQ这是后话?/p>

也就是说for k,v in pairs(tbtest) do q样的遍历顺序ƈ非是tbtest中table的排列顺序,而是Ҏtbtest中key的hash值排列的序来遍历的?/p>

 

当然Q同时lua也提供了按照key的大顺序来遍历的,注意Q是大小序Q仍然不是key定义的顺序,q种遍历方式是for k,v in ipairs(tbtest) do?/p>

for k,v in ipairs(tbtest) do q样的@环必要求tbtest中的key为顺序的Q而且必须是从1开始,ipairs只会?开始按q箋的key序遍历到key不连lؓ止?/p>

  1. tbtest = {  
  2. [1] = 1,  
  3. [2] = 2,  
  4. [3] = 3,  
  5. [5] = 5,  
  6.  
  7. for k,v in ipairs(tbtest) do  
  8. print(v)  
  9. end 

只会打印1Q?Q?。?则不会显C?/p>

  1. local tbtest = {  
  2. [2] = 2,  
  3. [3] = 3,  
  4. [5] = 5,  
  5.  
  6. for k,v in ipairs(tbtest) do  
  7. print(v)  
  8. end 

q样׃个都不会打印?/p>

 

W三U遍历方式有一U神奇的W号'#'Q这个符L作用是是获取table的长度,比如Q?/p>

  1. tbtest = {  
  2. [1] = 1,  
  3. [2] = 2,  
  4. [3] = 3,  
  5. }  
  6. print(#(tbtest)) 

打印的就?

  1. tbtest = {  
  2. [1] = 1,  
  3. [2] = 2,  
  4. [6] = 6,  
  5. }  
  6. print(#(tbtest)) 

q样打印的就?Q而且和table内的定义序没有关系Q无Z是否先定义的key?的|‘#’都会查找key?的值开始?/p>

如果table的定义是q样的:

  1. tbtest = {  
  2. ["a"] = 1,  
  3. [2] = 2,  
  4. [3] = 3,  
  5.  
  6. print(#(tbtest)) 

那么打印的就?了。因?#8216;#’没有扑ֈkey?的倹{同P

  1. tbtest = {  
  2. [“a”] = 1,  
  3. [“b”] = 2,  
  4. [“c”] = 3,  
  5. }  
  6. print(#(tbtest)) 

打印的也?

所以,for i=1, #(tbtest) doq种遍历Q只能遍历当tbtest中存在key?的value时才会出现结果,而且是按照key?开始依ơ递增1的顺序来遍历Q找C个递增不是1的时候就l束不再遍历Q无论后面是否仍然是序的keyQ比如:

 

table.maxn获取的只针对整数的keyQ字W串的key是没办法获取到的Q比如:

  1. tbtest = {  
  2. [1] = 1,  
  3. [2] = 2,  
  4. [3] = 3,  
  5. }  
  6. print(table.maxn(tbtest)) 
  7.  
  8.  
  9. tbtest = {  
  10. [6] = 6,  
  11. [1] = 1,  
  12. [2] = 2,  
  13. }  
  14. print(table.maxn(tbtest)) 

q样打印的就??Q而且和table内的定义序没有关系Q无Z是否先定义的key?的|table.maxn都会获取整数型key中的最大倹{?/p>

如果table的定义是q样的:

  1. tbtest = {  
  2. ["a"] = 1,  
  3. [2] = 2,  
  4. [3] = 3,  
  5. }  
  6. print(table.maxn(tbtest)) 

那么打印的就?了。如果table是:

  1. tbtest = {  
  2. [“a”] = 1,  
  3. [“b”] = 2,  
  4. [“c”] = 3,  
  5. }  
  6. print(table.maxn(tbtest))  
  7. print(#(tbtest)) 

那么打印的就全部?了?/p>

 

 

换句话说Q事实上因ؓlua中table的构造表辑ּ非常灉|Q在同一个table中,你可以随意定义各U你惌的内容,比如Q?/p>

  1. tbtest = {  
  2. [1] = 1,  
  3. [2] = 2,  
  4. [3] = 3,  
  5. ["a"] = 4,  
  6. ["b"] = 5,  

同时׃q个灉|性,你也没有办法获取整个table的长度,其实在coding的过E中Q你会发玎ͼ你真正想要获取整个table长度的地方几乎没有,你总能采取一U非常y妙的定义方式Q把q种需要获取整个table长度的操作避免掉Q比如:

  1. tbtest = {  
  2. tbaaa = {  
  3. [1] = 1,  
  4. [2] = 2,  
  5. [3] = 3,  
  6. },  
  7. ["a"] = 4,  
  8. ["b"] = 5,  

你可能会惊讶Q上面这Utable该如何遍历呢Q?/p>

  1. for k, v in pairs(tbtest) do  
  2. print(k, v)  
  3. end 

输出是:a 4 b 5 tbaaa table:XXXXX?/p>

由此你可以看刎ͼ其实在table中定义一个tableQ这个table的名字就是keyQ对应的内容其实是table的地址?/p>

当然Q如果你?/p>

  1. for k, v in ipairs(tbtest) do  
  2. print(k,v)  
  3. end 

来遍历的话,׃么都不会打印Q因为没有key?的倹{但当你增加一个key?的值时Qipairs只会打印那一个|现在你明白ipairs是如何工作的吧?/p>

既然q里谈到了遍历,p一下目前看到的几种针对table的遍历方式:

for i=1, #tbtest do --q种方式无法遍历所有的元素Q因?#'只会获取tbtest中从key?开始的keyq箋的那几个元素Q如果没有key?Q那么这个@环将无法q入

for i=1, table.maxn(tbtest) do --q种方式同样无法遍历所有的元素Q因为table.maxn只会获取key为整C最大的那个敎ͼ遍历的元素其实是查找 tbtest[1]~tbtest[整数key中最大值]Q所以,对于string做key的元素不会去查找Q而且q么查找的效率低下,因ؓ如果你整?key中定义的最大的key?0000Q然?0000以下的key没有几个Q那么这么遍历会费很多旉Q因Z?开始直?0000每一个元素都 会查找一遍,实际上大多数元素都是不存在的Q比如:

  1. tbtest = {  
  2. [1] = 1,  
  3. [10000] = 2,  
  4. }  
  5. local count = 0  
  6. for i=1, table.maxn(tbtest) do  
  7. count = count + 1  
  8. print(tbtest[i])  
  9. end  
  10. print(count) 

你会看到打印l果是多么的坑爹Q只??0000是有意义的,其他的全是nilQ而且count?0000。耗时非常久。一般我不这么遍历。但是有一U情况下又必这么遍历,q个在我的工作中q真的遇CQ这是后话,{讲完了再谈?/p>

  1. for k, v in pairs(tbtest) do 

q个是唯一一U可以保证遍历tbtest中每一个元素的方式Q别高兴的太早,q种遍历也有它自w的~点Q就是遍历的序不是按照tbtest定义的顺序来遍历的,q个前面讲到q,当然Q对于不需要顺序遍历的用法Q这个是唯一可靠的遍历方式?/p>

  1. for k, v in ipairs(tbtest) do 

q个只会遍历tbtest中key为整敎ͼ而且必须?开始的那些q箋元素Q如果没?开始的keyQ那么这个遍历是无效的,我个U遍历方 式完全可以被攚wtable和for i=1, #(tbtest) do的方式来代替Q因为ipairs的效果和'#'的效果,在遍历的时候是cM的,都是按照key的递增1序来遍历?/p>

好,再来谈谈Z么我需要用table.maxnq种非常费的方式来遍历Q在工作中, 我遇C个问题,是需要把当前的周序,转换成对应的奖励Q简单来_是从一个活动开始算P每周的奖励都不是固定的,比如1~4周给一U奖励,5~8 周给另一U奖励,或者是一U排名奖励,1~8名给一U奖励,9~16名给另一U奖励,q种情况下,我根据长久的C语言的习惯,会把table定义成这个样 子:

  1. tbtestAward = {  
  2. [8] = 1,  
  3. [16] = 3,  

q个代表Q?~8l奖?Q?~16l奖?。这样定义的好处是奖励我只需要写一ơ(q里的奖q数字做了化,实际上奖׃是一个大?tableQ里面还有非常复杂的l构Q。然后我遇C个问题,x需要根据周序数Q或者是排名序数来确定给哪一U奖励,比如当前周序数是5Q那么我应该 l我定义好的key?的那一档奖励,或者当前周序数?5Q那么我应该l奖?。由此读者看出,其实我定义的key是一个分界,于q个key而大于上 一个keyQ那么就l这个key的奖励,q就是我判断的条件。逻辑上没有问题,但是lua的遍历方式却把我狠狠地坑了一把。读者可以自己想一x上面介绍 ?U遍历方式,该用哪一U来实现我的q种需求呢Q这个函数的大致框架如下Q?/p>

  1. function GetAward(nSeq)  
  2. for 遍历整个奖励?nbsp;do  
  3. if 满key的条?nbsp;then  
  4. return q回对应奖励的key  
  5. end  
  6. end  
  7. return nil  
  8. end 

我也不卖兛_了,分别来说一说吧Q首先因为我的key不是q箋的,而且没有key?的|所以ipairs?#'遍历是没用的。这U情况下理想 的遍历貌似是pairsQ因为它会遍历我的每一个元素,但是读者不要忘CQpairs遍历q是按照我定义的顺序来遍历Q如果我真的使用的条件是Q序?nSeq于q个key而大于上一个keyQ那么就q回q个key。那么我无法保证E序执行的正性,因ؓkey的顺序有可能是ؕ的,也就是有可能先遍?到的是key?6的|然后才是key?的倹{?/p>

q么看来我只剩下table.maxnq么一U方式了Q于是我写下了这U代码:

  1. for i=1, table.maxn(tbtestAward) do  
  2. if tbtestAward[i] ~= nil then  
  3. if nSeq <= i then  
  4. return i  
  5. end  
  6. end  
  7. end  

q么写效率确实低下,因ؓ实际上还是遍历了从key?开始直到key为table.maxn中间的每一个|不过能够满我上面的要求。当时我?q么实现的,因ؓq个奖励表会不断的发生变化,q样我每ơ修改只需要修改这个奖pp够满求了Q后来我想了惻I觉得其实我如果自己再定义一个序数{ 换成对应的奖励数U类的表可以避免这U坑爹的操作了,不过如果奖励发生修改Q我需要统一排查的地方就不止q个奖励表了Q权衡再三,我还是没有改Q就q么 写了。没办法Q不断变化的需求已l把我磨l的忘记了程序的最高理惟뀂我甚至愿意牺牲法的效率而去q求改动的稳定性。在此哀悼程序员的无奈。我q种旉?I间的做法确实不知道好不好?/p>

后来我在《Programming In Lua》中看到了一个神奇的q代器,使用它就可以辑ֈ我想要的q种遍历方式Q而且不需要去遍历那些不存在的key。它的方法是把你所需要遍历的table 里的key按照遍历序攑ֈ另一个时的table中去Q这样只需要遍历这个时的table按顺序取出原table中的key可以了。如下:

首先定义一个P代器Q?/p>

  1. function pairsByKeys(t)  
  2.     local a = {}  
  3.     for n in pairs(t) do  
  4.         a[#a+1] = n  
  5.     end  
  6.     table.sort(a)  
  7.     local i = 0  
  8.     return function()  
  9.         i = i + 1  
  10.         return a[i], t[a[i]]  
  11.     end  
  12. end 

然后在遍历的时候用这个P代器可以了Qtable同上Q遍历如下:

  1. for key, value in pairsByKeys(tbtestAward) do  
  2.  if nSeq <= key then  
  3. return key  
  4. end  
  5. end 

q且后来我发现有了这个P代器Q我Ҏ不需要先做一步获取是哪一档次的奖q操作Q直接用这个P代器q行发奖可以了。大师就是大师,我怎么没惛_呢!

q有些话我还没有_比如上面数值型遍历也ƈ非是像看h那样q行遍历的,比如下面的遍历:

  1. tbtest = {  
  2.     [1] = 1,  
  3.     [2] = 2,  
  4.     [3] = 3,  
  5.     [5] = 5,  
  6.  
  7. for i=1, #(tbtest) do  
  8.     print(tbtest[i])  
  9. end 

打印的顺序是Q?Q?Q?。不会打?Q因?已经不在table的数l数据块中了Q我估计是被攑ֈ了hash数据块中Q但是当我修改其中的一些keyӞ比如Q?/p>

  1. tbtest = {  
  2.     [1] = 1,  
  3.     [2] = 2,  
  4.     [4] = 4,  
  5.     [5] = 5,  
  6.  
  7. for i=1, #(tbtest) do  
  8.     print(tbtest[i])  
  9. end 

打印的内容却是:1Q?QnilQ?Q?。这个地方又遍历C中间没有的key|q且q能l箋遍历下去。我最q正在看lua源码中table的实 现部分,已经明白了是怎么回事Q不q我想等我能够更加清晰的阐述lua中table的实现过E了再向大家介绍。用我师傅的话说是不要使用一些未定义的行 为方法,避免在工作中出错Q不q工作外Q我q是希望能明白未定义的行Z那些必然性,o(|Ӟ`|?o 唉!因果论的孩子伤不赗等我下一博文分析lua源码中table的实现就能够更加清晰的说明这些了?/p>



多彩人生 2014-08-25 14:29 发表评论
]]>
lua require dofile loadfile区别 http://www.shnenglu.com/colorful/archive/2014/08/22/208088.html多彩人生多彩人生Fri, 22 Aug 2014 01:24:00 GMThttp://www.shnenglu.com/colorful/archive/2014/08/22/208088.htmlhttp://www.shnenglu.com/colorful/comments/208088.htmlhttp://www.shnenglu.com/colorful/archive/2014/08/22/208088.html#Feedback0http://www.shnenglu.com/colorful/comments/commentRss/208088.htmlhttp://www.shnenglu.com/colorful/services/trackbacks/208088.htmlhttp://blog.163.com/hbu_lijian/blog/static/126129153201422902256778/
1.dofile与loadfile
dofile 当作Luaq行代码的chunk的一U原始的操作。dofile实际上是一个辅助的函数。真正完成功能的函数是loadfileQ与dofile不同的是 loadfile~译代码成中间码q且q回~译后的chunk作ؓ一个函敎ͼ而不执行代码Q另外loadfile不会抛出错误信息而是q回错误代。我们可 以这样定义dofileQ?wbr>
function dofile (filename)
local f = assert(loadfile(filename))
return f()
end
?果loadfilep|assert会抛出错误。loadfile更加灉|。在发生错误的情况下Qloadfileq回nil和错误信息,q样我们可?自定义错误处理。另外,如果我们q行一个文件多ơ的话,loadfile只需要编译一ơ,但可多次q行。dofile却每ơ都要编译?/div>
2.loadstring与loadfile
loadstring与loadfile怼Q只不过它不是从文g里读入chunkQ而是从一个串中读入?/div>
f = loadstring("i = i + 1")
loadstring 函数功能强大Q但使用旉多加心。确认没有其它简单的解决问题的方法再使用。loadfile和loadstring都不会抛出错误,如果发生错误他们 返回nil加上错误信息。另外,loadfile和loadstring都不会有边界效应产生Q他们仅仅编译chunk成ؓ自己内部实现的一个匿名函 数。通常对他们的误解是他们定义了函数。Lua中的函数定义是发生在q行时的赋D不是发生在~译时?/div>
loadstring通常?于运行程序外部的代码Q比如运行用戯定义的代码。注意:loadstring期望一个chunkQ即语句。如果想要加载表辑ּQ需要在表达式前?returnQ那样将q回表达式的倹{loadstringq回的函数和普通函CP可以多次被调用?/div>
print "enter your expression:"
local l = io.read()
local func = assert(loadstring("return " .. l))
print("the value of your expression is " .. func())
3.require与dofile
。粗略的说require和dofile完成同样的功能但有两点不同:
1. require会搜索目录加载文?/div>
2. require会判断是否文件已l加载避免重复加载同一文g。由于上q特征,require在Lua中是加蝲库的更好的函数?/div>
require 使用的\径和普通我们看到的路径q有些区别,我们一般见到的路径都是一个目录列表。require的\径是一个模式列表,每一个模式指明一U由虚文件名 Qrequire的参敎ͼ转成实文件名的方法。更明确地说Q每一个模式是一个包含可选的问号的文件名。匹配的时候Lua会首先将问号用虚文g名替换,然后 看是否有q样的文件存在。如果不存在l箋用同LҎ用第二个模式匚w。例如,路径如下Q?span style="line-height: 28px;">?;?.lua;c:\windows\?;/usr/local/lua/?/?.lua 
调用q程如下Q?/span>
lili
lili.lua
c:\windows\lili
/usr/local/lua/lili/lili.lua
q会有so/dll文g?/div>
Z定路径QLua首先查全局变量LUA_PATH是否Z个字W串Q如果是则认个串是路径Q否则require查环境变量LUA_PATH的|如果两个都失败require使用固定的\径(典型??;?.lua"Q?/div>
一个\径中的模式也可以不包含问可只是一个固定的路径Q比如:?;?.lua;/usr/local/default.lua。这U情况下Qrequire没有匚w的时候就会用这个固定的文gQ当然这个固定的路径必须攑֜模式列表的最后才有意义)


多彩人生 2014-08-22 09:24 发表评论
]]> lua中的require机制http://www.shnenglu.com/colorful/archive/2014/08/21/208082.html多彩人生多彩人生Thu, 21 Aug 2014 09:08:00 GMThttp://www.shnenglu.com/colorful/archive/2014/08/21/208082.htmlhttp://www.shnenglu.com/colorful/comments/208082.htmlhttp://www.shnenglu.com/colorful/archive/2014/08/21/208082.html#Feedback0http://www.shnenglu.com/colorful/comments/commentRss/208082.htmlhttp://www.shnenglu.com/colorful/services/trackbacks/208082.html
http://blog.chinaunix.net/uid-552961-id-2736410.html

lua中的require机制

    Z方便代码理Q通常会把lua代码分成不同的模块,然后在通过require函数把它们加载进来?br />现在看看lua的require的处理流E?br />
1、require机制相关的数据和函数
    package.path:保存加蝲外部模块(lua?模块"?文g"q两个概늚分界比较含糊Q因个值在不同的时M扮演不同的角?的搜?路径Q这U\径是"模板式的路径"Q它里面会包含可替代W号"?",q个W号会被替换Q然后lua查找q个文g是否存在Q如果存在就会调用其中特定的?口。典型的gؓ:
    "./?.lua;./?.lc;/usr/local/?/init.lua"
    如果lua代码中调?require("hello.world")
    那么lua会依ơ查找:
    ./hello/world.lua ==>q里"hello.world"变成?hello/world",q替换了模型"./?.lua"
    ./hello/world.lc
    .....
    (q种处理方式和pythoncMQ只不过不需要__init__.py,也有调用python中的__init__.py)
    package.path在虚拟机启动的时候设|,如果存在环境变量LUA_PATHQ那么就用该环境变量作ؓ
    它的|q把q个环境变量中的";;"替换为luaconf.h中定义的默认|如果不存在该变量q接?br />    luaconf.h定义的默认?br />    
    package.cpath:作用和packag.path一?但它是用于加载第三方c库的。它的初始值可以通过环境变量
    LUA_CPATH来设|?br />    
    package.loadlib(libname, func):相当与手工打开c库libname, q导出函数funcq回Qloadlib其实是ll_loadlib
    

2.require的处理流E:
   require(modelname)
   require(在lua中它是ll_require函数)的查N序如下:
       a.首先在package.loaded查找modelname,如果该模块已l存在,q接返回它的?br />       b.在package.preload查找modelname, 如果preload存在Q那么就把它作ؓloaderQ调用loader(L)
       c.Ҏpackage.path的模式查找lua库modelnameQ这个库是通过module函数定义的,对于层的lua库,文g名和库名是一 L而且不需要调用显式地在lua文g中调用module函数(在ll_require函数中可以看到处理方?Q也是说lua会根据lua文g直接?成一个loader的初始化q程?br />       d.Ҏpackage.cpath查找c库,q个库是W合lua的一些规范的(exporth一定特征的函数接口)Qlua先已动态的方式加蝲该c库,然后在库中查扑ƈ调用相应名字的接口,例如:luaopen_hello_world
       e.已第一?."为分Ԍ模块名划分?(main, sub)的Ş式,Ҏpackage.cpath查找mainQ如果存在,加载该库ƈ查询相应的接?luaopen_main_subQ例如:先查?hello库,q查询luaopen_hello_world接口
       f.得到loder后,用modname作ؓ唯一的参数调用该loader函数。当然参数是通过lua的栈传递的Q所以loader的原型必ȝ合lua的规?int LUA_FUNC(lua_State *L)
         
       ll_require会将q个loader的返回值符lpackage.loaded[modelname],如果loader不返回值同?package.loaded[modelname]不存在时, ll_require׃把package.loaded[modelname]设ؓtrue。最后ll_reuqire把package.loaded [modelname]q回l调用者?br />    

3.module的处理流E?br />    module(name, cb1, cb2, ...)
    
    a.如果package.loaded[name]是一个tableQ那么就把这个table作ؓ一个mod
    b.如果全局变量name是一个tableQ就把这个全局变量作ؓ一个mod
    c.创徏table:t = {[name]=package.loaded[name], ["_NAME"]=name, ["_M"]=t, ["_PACKAGE"]=*name*(删除了最后的".XXXX"部分)}. 如果name是一个以点分割的Ԍ那么得到的modcMq个样子Q?br />      hello.world==> {["hello"]={["world"]={XXXXXXX}}}
    d.依次调用cbsQ?br />      cb1(mod), cb2(mod),...
      
    e.当前模块的环境讄为mod,同时把package.loaded[name] = mod    
    

  清楚了lua关于模块的处理,比较容易理解写lua扩展的细节了^_^?


多彩人生 2014-08-21 17:08 发表评论
]]>lua学习http://www.shnenglu.com/colorful/archive/2014/08/08/207945.html多彩人生多彩人生Fri, 08 Aug 2014 09:01:00 GMThttp://www.shnenglu.com/colorful/archive/2014/08/08/207945.htmlhttp://www.shnenglu.com/colorful/comments/207945.htmlhttp://www.shnenglu.com/colorful/archive/2014/08/08/207945.html#Feedback0http://www.shnenglu.com/colorful/comments/commentRss/207945.htmlhttp://www.shnenglu.com/colorful/services/trackbacks/207945.html

----------------------------------------------------------------------------------

头文件lua.h定义了Lua提供的基函数。其中包括创Z个新的Lua环境的函敎ͼ如lua_openQ,调用 Lua函数Q如lua_pcallQ的函数Q读?写入Lua环境的全局变量的函敎ͼ注册可以被Lua代码调用的新函数的函敎ͼ{等。所有在lua.h?被定义的都有一个lua_前缀?/p>

头文件lauxlib.h定义了辅助库QauxlibQ提供的函数。同P所有在其中定义的函数等都以luaL_打头Q例如,luaL_loadbufferQ。辅助库利用lua.h中提供的基础函数提供了更高层ơ上的抽象;所有Lua标准库都使用了auxlib?/p>


----------------------------------------------------------------------------------

在控制台 使用 require 老是p|

后来发现要修改一?package.path

require搜烦模块时是Ҏpackage.path讄路径来搜索的


require搜烦路径

package.path   -- lua模块路径

package.cpath    -- dll so 库\?br />


package.path = package.path..';d:\?.lua'


// require mylua.lua

require 'mylua' 


------------------------------------------------------------------------------------



多彩人生 2014-08-08 17:01 发表评论
]]>lua5.1.5 安装http://www.shnenglu.com/colorful/archive/2013/07/16/201868.html多彩人生多彩人生Tue, 16 Jul 2013 08:54:00 GMThttp://www.shnenglu.com/colorful/archive/2013/07/16/201868.htmlhttp://www.shnenglu.com/colorful/comments/201868.htmlhttp://www.shnenglu.com/colorful/archive/2013/07/16/201868.html#Feedback0http://www.shnenglu.com/colorful/comments/commentRss/201868.htmlhttp://www.shnenglu.com/colorful/services/trackbacks/201868.htmllua5.1.5 安装

lua默认~译出的是静态库, 要生成动态库需作如下修?
1: src/Makefile
   如果?4位系l? 在CFLAGS后加 -fPIC 参数
   ?8行左叛_ LUA_SO= liblua.so
   ALL_T后加 $(LUA_SO)
   60行左叛_生成规则:
   $(LUA_SO): $(CORE_O) $(LIB_O)
             $(CC) -o $@ -shared $? -ldl -lm
2: lua根目录下?Makefile
   修改TO_LIB ?TO_LIB= liblua.a liblua.so

修改完后开始安?br />make linux
make install

q样在lua根目录下会生成liblua.so, liblua.so copy?usr/local/lib?br />cp liblua.so /usr/local/lib

q样可以了


多彩人生 2013-07-16 16:54 发表评论
]]>lua fPIC errorhttp://www.shnenglu.com/colorful/archive/2013/04/23/199659.html多彩人生多彩人生Tue, 23 Apr 2013 06:50:00 GMThttp://www.shnenglu.com/colorful/archive/2013/04/23/199659.htmlhttp://www.shnenglu.com/colorful/comments/199659.htmlhttp://www.shnenglu.com/colorful/archive/2013/04/23/199659.html#Feedback0http://www.shnenglu.com/colorful/comments/commentRss/199659.htmlhttp://www.shnenglu.com/colorful/services/trackbacks/199659.html

安装luaQ?/p>

tar zxvf lua-5.1.4.tar.gz

cd lua-5.1.4

如果你的服务器是64位的Q这时要调整一下MakefileQvi src/MakefileQ在CFLAGS里加?fPICQ否则会出错Q?/p>

/usr/bin/ld: /usr/local/lib/liblua.a(lapi.o):

relocation R_X86_64_32 against `luaO_nilobject_' can not be used when making a shared object;

recompile with -fPIC

/usr/local/lib/liblua.a: could not read symbols: Bad value

接下来不用执行常见的configureQ直接makeQ?/p>

make linux

make install



多彩人生 2013-04-23 14:50 发表评论
]]>luabind常用Ҏȝ http://www.shnenglu.com/colorful/archive/2012/10/18/193495.html多彩人生多彩人生Thu, 18 Oct 2012 15:45:00 GMThttp://www.shnenglu.com/colorful/archive/2012/10/18/193495.htmlhttp://www.shnenglu.com/colorful/comments/193495.htmlhttp://www.shnenglu.com/colorful/archive/2012/10/18/193495.html#Feedback0http://www.shnenglu.com/colorful/comments/commentRss/193495.htmlhttp://www.shnenglu.com/colorful/services/trackbacks/193495.htmlluabind比较复杂Q功能包|万象,但用v来比较简单,特别是最常用的方法只有几个,下面l合一个简单的例子ȝ一下?    在我们游戏应用中Q一般都是已c++Z导的Q也是说c++d调用lua脚本?br />
先写一个比较常见的lua脚本Q?/div>
  1. nGlobal = 10 --一个全局的整形变?nbsp;  
  2. strGlobal = "hello i am in lua" --一个全局的字W串变量   
  3. --一个返回gؓintcd的函?nbsp;  
  4. function add(a, b)   
  5.     return a+b   
  6. end   
  7. --一个返回gؓstringcd的函?nbsp;  
  8. function strEcho(a)   
  9.     print(a) 10   
  10.     return 'haha i have print your input param'   
  11. end   
  12. cppapi.testFunc() --调用c++暴露的一个测试函?nbsp;  
  13. t={name='ettan', age=23, desc='正D季年?}  
 
////////////////////////////////////lua脚本l束
下面写c++函数中的调用?/div>
  1. #include<iostream>  
  2. #include<string>  
  3. using namespace std;  
  4. #include<lua.hpp>  
  5. #include<luabind/function.hpp>  
  6. void testFunc()  
  7. {  
  8.     cout<<"helo there, i am a cpp fun"<<endl;  
  9. }  
  10. int main(int argc, char* argv[])  
  11. {  
  12.     //首先声明luaState环境  
  13.     using namespace luabind;  
  14.     lua_State* L = lua_open();  //也可以用luaL_newState()函数  
  15.     luaL_openlibs(L);   //注意lua默认库打开Q要不会出现N多错误的Q比如print函数都没?nbsp; 
  16.     //c++中的函数暴露llua  
  17.     module(L, "cppapi")  
  18.     [  
  19.         def("testFunc", (void(*)(void))testFunc)  
  20.     ];  
  21.     //加蝲lua脚本Q我们时v名test.lua  
  22.     luaL_dofile(L, "test.lua");  
  23.     try  
  24.     {  
  25.         //调用lua中的整Ş全局变量  
  26.         int nLuaGlobal =     luabind::object_cast<int>(luabind::globals(L)["nGlobal"]) ;  
  27.         //调用lua中的字符串变?nbsp; 
  28.         string strLuaGlobal = luabind::object_cast<string>(luabind::globals(L)["strGlobal"]);  
  29.         //获取table,Ҏ一Q通过luabind::object 固有Ҏ  
  30. luabind::object luaTable = luabind::globals(L)["t"] ;  
  31. string name=luabind::object_cast<string>(luaTable["name"]) ;  
  32.         int age = luabind::object_cast<int>(luaTable["age"]) ;  
  33.         //获取tableQ方法二Q通过gettable  
  34.         string desc = luabind::object_cast<string>(luabind::gettable(luaTable,"desc"));  
  35.         //下面是调用lua中函?nbsp; 
  36.         int nAddRes = luabind::call_function<int>(L, "add", 3, 4) ;  
  37.         string strEchoRes = luabind::call_function<string>(L, "strEcho", "c++参数") ;  
  38.     }  
  39.     catch(...)  
  40.     {  
  41.         cout<<"error"<<endl;  
  42.     }  
  43.     return 0;  
  44. }  
 
    我们目前常用的方法暂时就有这些,当然在实际编码中Qc++暴露llua的经常是c++cM的函敎ͼ只要E加修改pQ?/div>


多彩人生 2012-10-18 23:45 发表评论
]]>linux 下安装luabindhttp://www.shnenglu.com/colorful/archive/2012/09/25/191985.html多彩人生多彩人生Tue, 25 Sep 2012 12:11:00 GMThttp://www.shnenglu.com/colorful/archive/2012/09/25/191985.htmlhttp://www.shnenglu.com/colorful/comments/191985.htmlhttp://www.shnenglu.com/colorful/archive/2012/09/25/191985.html#Feedback0http://www.shnenglu.com/colorful/comments/commentRss/191985.htmlhttp://www.shnenglu.com/colorful/services/trackbacks/191985.html  luabind需要boost 和lua, 请先安装boost, lua
  luabind用到lua的动态库Q请在安装lua时编译出 liblua.so

  a: export BOOST_ROOT=/home/zc/tools/boost_1_48_0
  b: export LUA_PATH=/usr/local/
  c: bjam stage --toolset=gcc --with-date_time --with-fpic --with-filesystem link=static debug release  --q一步可以不?br />   d: bjam install


多彩人生 2012-09-25 20:11 发表评论
]]>关于lua5.1.4找不到luaL_openlibs的问?/title><link>http://www.shnenglu.com/colorful/archive/2012/09/25/191982.html</link><dc:creator>多彩人生</dc:creator><author>多彩人生</author><pubDate>Tue, 25 Sep 2012 11:53:00 GMT</pubDate><guid>http://www.shnenglu.com/colorful/archive/2012/09/25/191982.html</guid><wfw:comment>http://www.shnenglu.com/colorful/comments/191982.html</wfw:comment><comments>http://www.shnenglu.com/colorful/archive/2012/09/25/191982.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/colorful/comments/commentRss/191982.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/colorful/services/trackbacks/191982.html</trackback:ping><description><![CDATA[忙了一下午Q最后才发现是src/Makefile里少数据<br /><div><div>LUAC_T=    luac<br />LUAC_O=    luac.o print.o<br />LUA_SO= liblua.so<br /><br />ALL_O= $(CORE_O) $(LIB_O) $(LUA_O) $(LUAC_O)<br />ALL_T= $(LUA_A) $(LUA_T) $(LUAC_T) $(LUA_SO)<br />ALL_A= $(LUA_A)<br /><br />default: $(PLAT)<br /><br />all:    $(ALL_T)<br /><br />o:    $(ALL_O)<br /><br />a:    $(ALL_A)<br /><br />$(LUA_A): $(CORE_O) $(LIB_O)<br />    $(AR) $@ $?<br />    $(RANLIB) $@<br /><br />$(LUA_T): $(LUA_O) $(LUA_A)<br />    $(CC) -o $@ $(MYLDFLAGS) $(LUA_O) $(LUA_A) $(LIBS)<br /><br />$(LUAC_T): $(LUAC_O) $(LUA_A)<br />    $(CC) -o $@ $(MYLDFLAGS) $(LUAC_O) $(LUA_A) $(LIBS)<br /><br />$(LUA_SO):$(CORE_O) $(LIB_O)<br />    $(CC) -o $@ -shared -fPIC $? -ldl -lm<br /></div></div><img src ="http://www.shnenglu.com/colorful/aggbug/191982.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/colorful/" target="_blank">多彩人生</a> 2012-09-25 19:53 <a href="http://www.shnenglu.com/colorful/archive/2012/09/25/191982.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>lua 安装http://www.shnenglu.com/colorful/archive/2012/09/25/191949.html多彩人生多彩人生Tue, 25 Sep 2012 06:23:00 GMThttp://www.shnenglu.com/colorful/archive/2012/09/25/191949.htmlhttp://www.shnenglu.com/colorful/comments/191949.htmlhttp://www.shnenglu.com/colorful/archive/2012/09/25/191949.html#Feedback0http://www.shnenglu.com/colorful/comments/commentRss/191949.htmlhttp://www.shnenglu.com/colorful/services/trackbacks/191949.html下蝲源文?br />tar zxvf lua.tar.gz
make linux
make install

提示找不到readline/readline.h
apt-get install libncurses5-dev libreadline5-dev


多彩人生 2012-09-25 14:23 发表评论
]]>
þ| 鶹һ99þþþ| ݺݾþ| þۺϾɫۺϾ99| ƷۺϾþõһҳ | þŷ޹ۺ| 㽶þþþ| Ļ˾Ʒþò| þ޹ҹƷƬ| VVþþ| 2020þþƷ| þþƷƵ| þþƷվ| þþۺ| ҹŷƷþþþþþ| ޳ɫWWWþվ| þþƷAVȫ| þøݾƷԴվ| һþaþþƷۺҹҹ| 777þþƷһ| Ʒþþþþþþþ| þerƷѹۿ8| þþȹ͵ۺ| þ͵wcŮ| þþþӰԺ| þþûɫƬ| þþþþþۺ| þþþֻоƷ| avɫۺϾþavɫۺ| ݺɫۺþö| Ӱһþҹײ | Ӱһþҹײ| 뾫Ʒþþþ| þۺɫɫ| ŷ㽶þۺվ| պþëƬ| þþƷһ| ŷþһ| 91ƷۺϾþ| þþƷަvDz| ܻƺ۵վþmimiɫ|