备忘,备忘。
使用lua_ref来引用变量
int m_nluaFuncRef ;
m_nluaFuncRef = lua_ref ( L , LUA_REGISTRYINDEX ); // 赋值,针对栈顶
lua_getref ( L , m_nluaFuncRef ); // 调用
lua_unref ( L , m_nluaFuncRef ); // 释放
遍历table
While traversing a table, do not call lua_tostring directly on a key,
unless you know that the key is actually a string. Recall that
lua_tostring changes the value at the given index; this confuses the
next call to lua_next
lua_pushnil ( L );
while ( lua_next ( L , nIndex ))
{
lua_pushvalue ( L , - 2 ); //lua_tostring key的时候会改变 key值,会导致遍历有问题,需要保护一下
const char * pszKey = lua_tostring ( L , - 1 );
const char * pszValue = lua_tostring ( L , - 2 );
Params [ pszKey ] = pszValue ;
lua_pop ( L , 2 );
}
创建table
lua_newtable ( L );
for ( int nLine = 2 ; nLine <= nLineCount ; nLine ++ )
{
lua_pushinteger ( L , nLine ); // key
lua_newtable ( L );
for ( int nCol = 1 ; nCol <= nColumnCount ; nCol ++ )
{
lua_pushstring ( L , xx -> pszKey );
lua_pushstring ( L , xx -> pszValue );
lua_settable ( L , - 3 );
}
lua_settable ( L , - 3 );
}
table操作
lua_PushObject ( g_pUIMgr -> m_pluaState , pNode );
lua_pushstring ( g_pUIMgr -> m_pluaState , CONTROL_KEY_NAME );
lua_gettable ( g_pUIMgr -> m_pluaState , - 2 );
nRetCode = lua_type ( g_pUIMgr -> m_pluaState , - 1 );
if ( nRetCode != lua_TNIL )
{
Log ( eLogWarning , "[SetControlName] Redefinition of %s" , pszMemberVariableName );
goto Exit0 ;
}
lua_pop ( g_pUIMgr -> m_pluaState , 2 );
lua_PushObject ( g_pUIMgr -> m_pluaState , pNode );
lua_pushstring ( g_pUIMgr -> m_pluaState , pszMemberVariableName );
lua_setfield ( g_pUIMgr -> m_pluaState , - 2 , CONTROL_KEY_NAME );
lua_pop ( g_pUIMgr -> m_pluaState , 1 );
Import的lua版本
Import 是我们一直以来对lua文件间访问的封装,它有三个优点:
解决文件间的循环依赖
每个文件是一个独立的沙盒,不会污染全局变量
方便支持热更新
最早的版本用C语言实现的,后来我认为用lua实现更容易理解:
(删除了对lua5.1的支持,如有需要可去github查看本文件历史。2016.04.15 )
local function GetFileKey ( name )
return "FILE:" .. name ;
end
function _G . Import ( name )
local key = GetFileKey ( name );
if _G [ key ] then
return _G [ key ];
end
local tb = {};
setmetatable ( tb , { __index = _G });
_G [ key ] = tb ;
local fn , msg = loadfile ( name , "t" , tb );
if not fn then
print ( string.format ( "Import [%s] filed. %s" , name , msg ));
return _G [ key ];
end
fn ();
return _G [ key ];
end
function _G . ReImport ( name )
local key = GetFileKey ( name );
if not _G [ key ] then
return ;
end
local fn , msg = loadfile ( name , "t" , _G [ key ]);
if not fn then
print ( string.format ( "Re import [%s] filed. %s" , name , msg ));
return ;
end
fn ();
end
5.1的时候metatable只支持userdata,5.2支持table和userdata了
local cmd = setmetatable ({}, { __gc = function () print ( "cmd clear" ) end })
print "set"
cmd = nil ;
collectgarbage ();
print "unset"
在5.1下不输出”cmd clear”,5.2下输出。
luajit相关
luajit与lua相比:
优点:
可以提高性能
可以使用ffi加快开发速度
缺点:
luajit 在 64 位平台下,只能使用 1G 内存。即使在同一进程内开辟多个 lua state 也不例外。查看代码可以知道,luajit 为了结合更高效的 gc ,使用了自己的内存管理器。这需要用一个 32 位的伪指针工作。为了适应 64 位平台,它强制让分配器分配出来的内存的高位都必须是 0 。所以,多个 lua state 也需要满足这个条件,而不可能突破 4G 的限制。
luajit 居然使用了 NaN Trick ,这导致 lightuserdata 仅有 48 位有效值(可见 luajit 的源代码 lj_obj.h)。
{…} 不同
function test ( ... )
local tb = { ... }
print ( # tb , unpack ( tb ))
end
test ( "as" , nil , 1 , 2 )
lua 输出
luajit输出
本文链接, 未经许可,禁止转载