Lua 5.4 Reference Manual - contents官方网站
void lua_call(lua_State *L, int nargs, int nresults);
void lua_callK(lua_State *L, int nargs, int nresults, lua_KContext ctx, lua_KFunction k);// allows the called function to yield
typedef int (*lua_CFunction)(lua_State *L);//自定义C函数,用于操作Lua中的变量或函数。
int lua_checkstack(lua_State *L, int n);//Ensures that the stack has space for at least n extra elements.
int lua_compare(lua_State *L, int index1, int index2, int op);
void lua_createtable(lua_State *L, int narr, int nrec);
//Parameter narr is a hint for how many elements the table will have as a sequence;
//Parameter nrec is a hint for how many other elements the table will have.
int lua_getfield(lua_State *L, int index, const char *k);
//Pushes onto the stack the value t[k], where t is the value at the given index;
int lua_getglobal(lua_State *L, const char *name);
//Pushes onto the stack the value of the global name.Returns the type of that value.
int lua_geti(lua_State *L, int index, lua_Integer i);
//Pushes onto the stack the value t[i], where t is the value at the given index.
int lua_getmetatable(lua_State *L, int index);
//If the value at the given index has a metatable, the function pushes that metatable onto the stack and returns 1.
int lua_gettable(lua_State *L, int index);
Pushes onto the stack the value t[k], where t is the value at the given index and k is the value on the top of the stack.
int lua_gettop(lua_State *L);
//Returns the index of the top element in the stack.
int lua_iscfunction(lua_State *L, int index)
int lua_isfunction(lua_State *L, int index)
int lua_isnumber(lua_State *L, int index)
Returns 1 if the value at the given index is a number or a string convertible to a number.
int lua_isstring(lua_State *L, int index)
Returns 1 if the value at the given index is a string or a number.
typedef ... lua_KContext;
lua_State *lua_newstate(lua_Alloc f, void *ud);
//Creates a new independent state and returns its main thread.
void lua_newtable(lua_State *L);
//Creates a new empty table and pushes it onto the stack. It is equivalent to lua_createtable(L, 0, 0).
int lua_next(lua_State *L, int index);
//Pops a key from the stack, and pushes a key-value pair from the table at the given index.
int lua_pcall(lua_State *L, int nargs, int nresults, int msgh);
//Calls a function(or a callable object) in protected mode.
//Like lua_call, lua_pcall always removes the function and its arguments from the stack.
int lua_pcallk(lua_State *L, int nargs, int nresults, int msgh, lua_KContext ctx, lua_KFunction k);
void lua_pop(lua_State *L, int n);
void lua_pushcclosure(lua_State *L, lua_CFunction fn, int n);
//Pushes a new C closure onto the stack.The parameter n tells how many upvalues this function will have.
//When a C function in created, it is possible to associate some values with it, the so called upvalues; these upvalues are the accessible to the function whenever it is called. This association is called a C closure.
//When n is zero, this function creates a light C function, which is just a pointer to the C function.
void lua_pushcfunction(lua_State *L, lua_CFunction f);
//Pushes a C function onto the stack.This function is equivalent to lua_pushcclosure with no upvalues.
void lua_pushglobaltable(lua_State *L)
//Pushes the global environment onto the stack.
void lua_pushlightuserdata(lua_State *L, void *P);
//Pushes a light userdata onto the stack.
//Userdata represent C values in Lua. A light userdata represents a pointer.
void lua_pushvalue(lua_State *L, int index)
//Pushes a copy of the element at the given index onto the stack.
void lua_rawset(lua_State *L, int index)
//Similar to lua_settable, but does a raw access. the value at index must be a table.
void lua_rawget(lua_State *L, int index)
//Similar to lua_gettable, but does a raw access. The value at index must be a table.
int lua_rawgetp(lua_State *L, int index, const void *P);
//Pushes onto the stack the value t[k], where t is the table at the given index and k is the pointer p represented as a light userdata. Returns the type of the pushed value.
void lua_register(lua_State *L, const char *name, lua_CFunction f);
//Sets the C function f as the new value of global name.It is defined as a macro:
//#define lua_register(L, n, f) (lua_pushcfunction(L,f), lua_setglobal(L, n))
void lua_remove(lua_State *L, int index)
//Removes the element at the given valid index, shifting down the elements above this index to fill the gap.
void lua_setfield(lua_State *L, int index, const char *k)
//Does the equivalent to t[k] = v, where t is the value at the given index and v is the value on the top of the stack.
void lua_setglobal(lua_State *L, const char *name)
//Pops a value from the stack and sets it as the new value of global name.
int lua_setiuservalue(lua_State *L, int index, int n)
//Pops a value from the stack and sets it as the new n-th user value associated to the full userdata at the given index. Returns 0 if the userdata does not have that value.
int lua_setmetatable(lua_State *L, int index)
//Pops a table or nil from the stack and sets that value as the new metatable for the value at the given index.(nil means no metatable)
void lua_settable(lua_State *L, int index);
//Does the equivalent to t[k] = v, where t is the value at the given index, v is the value on the top of the stack, and k is the value just below the top.
void lua_settop(lua_State *L, int index);
//转换函数
int lua_toboolean(lua_State *L, int index);
//Converts the Lua value at the given index to a C boolean value (0 or 1)
lua_CFunction lua_tocfunction(lua_State *L, int index);
//Converts a value at the given index to a C function. That value must be a C function.
const void* lua_topointer(lua_State *L, int index)
//Converts the value at the given index to a generic C pointer(void*). The value can be a userdata, a table, a thread, a string, or a function; otherwise returns NULL.
void* lua_touserdata(lua_State *L, int index)
//If the value at the given index is a full userdata, returns its memory-block address. If the value is a light userdata, returns its value(a pointer). otherwise returns NULL.
int lua_upvalueindex(int i);
//Returns the pseudo-index that represents the i-th upvalue of the running function. i must be in the range [1,256]
void lua_toclose(lua_State *L, int index);
void
Unlua、Slua均是腾讯开源的UE lua框架。
// Tencent is pleased to support the open source community by making UnLua available.
//
// Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
//
// Licensed under the MIT License (the "License");
// you may not use this file except in compliance with the License. You may obtain a copy of the License at
//
// http://opensource.org/licenses/MIT
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and limitations under the License.
#include "UELib.h"
#include "Binding.h"
#include "Registries/ClassRegistry.h"
#include "LuaCore.h"
#include "LuaDynamicBinding.h"
#include "LuaEnv.h"
#include "Registries/EnumRegistry.h"
static const char* REGISTRY_KEY = "UnLua_UELib";
static const char* NAMESPACE_NAME = "UE";
static int UE_Index(lua_State* L)
{
const int32 Type = lua_type(L, 2);
if (Type != LUA_TSTRING)
return 0;
const char* Name = lua_tostring(L, 2);
const auto Exported = UnLua::FindExportedNonReflectedClass(Name);
if (Exported)
{
Exported->Register(L);
lua_rawget(L, 1);
return 1;
}
const char Prefix = Name[0];
const auto& Env = UnLua::FLuaEnv::FindEnvChecked(L);
if (Prefix == 'U' || Prefix == 'A' || Prefix == 'F')
{
const auto ReflectedType = UnLua::FClassRegistry::LoadReflectedType(Name + 1);
if (!ReflectedType)
return 0;
if (ReflectedType->IsNative())
{
if (auto Struct = Cast<UStruct>(ReflectedType))
Env.GetClassRegistry()->Register(Struct);
}
else
{
UE_LOG(LogUnLua, Warning, TEXT("attempt to load a blueprint type %s with UE namespace, use UE.UClass.Load or UE.UObject.Load instead."), UTF8_TO_TCHAR(Name));
return 0;
}
}
else if (Prefix == 'E')
{
const auto ReflectedType = UnLua::FClassRegistry::LoadReflectedType(Name);
if (!ReflectedType)
return 0;
if (ReflectedType->IsNative())
{
if (auto Enum = Cast<UEnum>(ReflectedType))
Env.GetEnumRegistry()->Register(Enum);
}
else
{
UE_LOG(LogUnLua, Warning, TEXT("attempt to load a blueprint enum %s with UE namespace, use UE.UObject.Load instead."), UTF8_TO_TCHAR(Name));
return 0;
}
}
lua_rawget(L, 1);
return 1;
}
extern int32 UObject_Load(lua_State *L);
extern int32 UClass_Load(lua_State *L);
static int32 Global_NewObject(lua_State *L)
{
int32 NumParams = lua_gettop(L);
if (NumParams < 1)
{
UNLUA_LOGERROR(L, LogUnLua, Log, TEXT("%s: Invalid parameters!"), ANSI_TO_TCHAR(__FUNCTION__));
return 0;
}
UClass *Class = Cast<UClass>(UnLua::GetUObject(L, 1));
if (!Class)
{
UNLUA_LOGERROR(L, LogUnLua, Log, TEXT("%s: Invalid class!"), ANSI_TO_TCHAR(__FUNCTION__));
return 0;
}
UObject* Outer = UnLua::GetUObject(L, 2);
if (!Outer)
Outer = GetTransientPackage();
FName Name = NumParams > 2 ? FName(lua_tostring(L, 3)) : NAME_None;
//EObjectFlags Flags = NumParams > 3 ? EObjectFlags(lua_tointeger(L, 4)) : RF_NoFlags;
{
const char *ModuleName = NumParams > 3 ? lua_tostring(L, 4) : nullptr;
int32 TableRef = LUA_NOREF;
if (NumParams > 4 && lua_type(L, 5) == LUA_TTABLE)
{
lua_pushvalue(L, 5);
TableRef = luaL_ref(L, LUA_REGISTRYINDEX);
}
FScopedLuaDynamicBinding Binding(L, Class, UTF8_TO_TCHAR(ModuleName), TableRef);
#if ENGINE_MAJOR_VERSION <= 4 && ENGINE_MINOR_VERSION < 26
UObject* Object = StaticConstructObject_Internal(Class, Outer, Name);
#else
FStaticConstructObjectParameters ObjParams(Class);
ObjParams.Outer = Outer;
ObjParams.Name = Name;
UObject* Object = StaticConstructObject_Internal(ObjParams);
#endif
if (Object)
{
UnLua::PushUObject(L, Object);
}
else
{
UNLUA_LOGERROR(L, LogUnLua, Log, TEXT("%s: Failed to new object for class %s!"), ANSI_TO_TCHAR(__FUNCTION__), *Class->GetName());
return 0;
}
}
return 1;
}
static constexpr luaL_Reg UE_Functions[] = {
{"LoadObject", UObject_Load},
{"LoadClass", UClass_Load},
{"NewObject", Global_NewObject},
{NULL, NULL}
};
int UnLua::UELib::Open(lua_State* L)
{
lua_newtable(L);
lua_pushstring(L, "__index");
lua_pushcfunction(L, UE_Index);
lua_rawset(L, -3);
lua_pushvalue(L, -1);
lua_setmetatable(L, -2);
lua_pushvalue(L, -1);
lua_pushstring(L, REGISTRY_KEY);
lua_rawset(L, LUA_REGISTRYINDEX);
luaL_setfuncs(L, UE_Functions, 0);
lua_setglobal(L, NAMESPACE_NAME);
// global access for legacy support
lua_getglobal(L, LUA_GNAME);
luaL_setfuncs(L, UE_Functions, 0);
lua_pop(L, 1);
#if WITH_UE4_NAMESPACE == 1
// 兼容UE4访问
lua_getglobal(L, NAMESPACE_NAME);
lua_setglobal(L, "UE4");
#elif WITH_UE4_NAMESPACE == 0
// 兼容无UE4全局访问
lua_getglobal(L, LUA_GNAME);
lua_newtable(L);
lua_pushstring(L, "__index");
lua_getglobal(L, NAMESPACE_NAME);
lua_rawset(L, -3);
lua_setmetatable(L, -2);
#endif
return 1;
}
void UnLua::UELib::SetTableForClass(lua_State* L, const char* Name)
{
lua_getglobal(L, NAMESPACE_NAME);
lua_pushstring(L, Name);
lua_pushvalue(L, -3);
lua_rawset(L, -3);
lua_pop(L, 1);
}