精华内容
下载资源
问答
  • skynet_启动lua服务

    2019-07-30 15:56:19
    skynet启动lua服务 每个skynet进程在启动的时候,都会启动一个lua层的launcher服务器,该服务主要负责skynet的运作期间进行创建其他lua服务. launcher是在 bootstrap.lua中启动的, skynet.launch(“snlua”,“launcher...

    Skynet学习

    skynet启动lua服务
    每个skynet进程在启动的时候,都会启动一个lua层的launcher服务器,该服务主要负责skynet的运作期间进行创建其他lua服务.
    launcher是在 bootstrap.lua中启动的, skynet.launch(“snlua”,“launcher”)) 这里启动,关于
    skynet.launch方法,后面会与描述.

    在skynet.lua中 skynet.newservice(),代码如下

     function skynet.newservice(name, ...) --启动一个LUA服务,实际上是给launcher发送消息实现的
         return skynet.call(".launcher", "lua" , "LAUNCH", "snlua", name, ...) 
     end
    

    调用skynet.lua中 skynet.call()

    function skynet.call(addr,typename,...) --阻塞发送消息
    	local p = proto[typename] --现根据名字取得对应的消息类别(table)
    	local session = c.send(addr,p.id,nil,p.pack(...)) --p.pack打包消息,然后发送消息,保存返回的会话
    	if session == nil then
    		error("call to invalid address" .. skynet.address(addr))
    	end
    	return p.unpack(yield_call(addr,session)) --挂起调用,解包返回的消息,消息大小
    end
    

    c.send 从lua-skynet.c的 luaopen_skynet_core中对应的函数名跟函数发生调用,send对应
    lsend函数,lsend调用send_message

    static int send_message(lua_State *L, int source,int idx_type){
    	struct skynet_context* context = lua_touserdata(L,lua_upvalueindex(1)); //从伪索引获取上下文
    	uint32_t dest = lua_tounsigned(L,1); //获取目标数字地址
    	const char* dest_string = NULL; //目标字符串地址
    	if(dest == 0) { //传入的是数字,而不是字符串
    		dest_string = get_dest_string(L,1); //获取目标字符串地址
    	}
    	int type = luaL_checkinteger(L,2); //获取消息类型
    	int session = 0;
    	if (lua_isnil(L,3) { //如果第三个参数是空,则是从skynet.call调用过来的
    		type |= PTYPE_TAG_ALLOCESSION; //skynet.call会在内部生成一个唯一session,所以这里需要设置分配会话标志
    	}else{
    		session = luaL_checkinteger(L,3); //获取会话
    		//skynet.send调用过来的传递的是0
    	}
    	int mtype == lua_type(L,4); //取得第四个参数的类型
    	switch(mtype) { //判断类型
    	case LUA_TSTRING:{ //如果是字符串类型
    		size_t len = 0;  //存放字符串长度
    		void* msg = (void*)lua_tolstring(L,4,&len); //获取字符串
    		if (len == 0 ) msg = NULL; 置空
    		if (dest_string){ //目标是字符串地址
    			session = sknet_sendname(context,0,dest_string,type,session,msg,len); 	
    		}esle {
    			session = skynet_send(context,0,dest,type,session,msg,len);
    		}
    		break;
    	}
    	case LUA_TLIGHTUSERDATA: { //用户数据
    		void * msg = lua_touserdata(L,4); //获取消息c指针
    		int size = luaL_checkinteger(L,5); //获取消息长度
    		         if (dest_string) {//如果目标是字符串地址
                 session = skynet_sendname(context, 0, dest_string, type | PTYPE_TAG_DONTCOPY, session, msg, size);//不需要拷贝消息数据
             } else {//如果目标是数字地址
                 session = skynet_send(context, 0, dest, type | PTYPE_TAG_DONTCOPY, session, msg, size);//不需要拷贝消息数据
             }   
             break;
    	}	
    	default:
    		luaL_error(L,"seynet.send invalid param %s", lua_typename(L, lua_type(L,4)));
    	}
    	if (session < 0 ) {
    	         // send to invalid address
             // todo: maybe throw error whould be better
             // 发送到无效的地址
             // 可能抛出一个错误更好
             return 0;	
    	}
        lua_pushinteger(L,session);//返回会话
        return 1;
    }
    

    这里调用skynet_server.c中的skynet_send()方法

    int skynet_send(struct_context* context,uint32_t source, uint32_t destination, int type, int session, void* data, size_t sz) {
    	if ((sz & HANDLE_MASK) != sz) { //判断消息是否过大
    		skynet_error(context,"The message to %x is too large (sz=%lu)",destination,sz);
    		skynet_free(data);
    		return -1;
    	}
    	_filter_args(context,type,&session,(void*)&data,&sz); //过滤参数
    	if(source == 0 ) { //源为0
    		source = context->handle; //设置源为自己
    	}
    	if (destination == 0){ //目的地址0
    		return session;
    	}
    	if (skynet_harbor_message_isremote(destination)) {//远程消息
    		struct remote_message* rmsg = skynet_malloc(sizeof(*rmsg));
    		rmsg->destination.handle = destination;
    		rmsg->message = data;
    		rmsg->sz = sz;
    		skynet_harbor_send(rmsg,source,session); //用harbor讲消息发出去
    	}else { //本地消息
    		struct skynet_message smsg; //定义一个skynet消息
    		smsg.source = source;
    		smsg.session = session;
    		smsg.data = data;
    		smsg.sz = sz;
    		//发送消息到目标的队列
    		if (skyet_context_push(destination,&smsg)) {
    			skynet_free(data); //push失败,释放数据
    			return -1;
    		}
    	}	
    	return session; //返回会话
    }
    

    这里的skynet_server.c中的skynet_context_push

    int skynet_context_push(uint32_t handle, struct skynet_message* message){
    	struct skynet_context* ctx= skynet_handle_grab(handle); //根据句柄获取上下文引用
    	if (ctx == NULL) {
    		return -1;
    	}
    	skynet_mq_push(ctx->queue,message); //将消息放入队列
    	skynet_context_release(ctx); //释放上下文,因为在skynet_handle_grab中调用了skynet_context_grab增加了上下文的引用计数
    	return 0;
    }
    

    这里调用到skynet_mq.c中的skynet_mq_push()

    void skynet_mq_push(struct message_queue* q,struct skynet_message* message){
    	assert(message);
    	SPIN_LOCK(q);
    	q->queue[q->tail] == *message; 
    	if (++q->tail > q->cap){
    		q->tail = 0;
    	}
    	if (q->head == q->tail) {
    		expand_queue(q);
    	}
    	if (q->in_global == 0) {
    		q->in_global = 	MQ_IN_GLOBAL;
    		skynet_golbalmq_push(q);
    	}
    	SPIN_UNLOCK(q);
    }
    

    这就是启动一个服务的逻辑就是向launcher的服务队列中发送了需要启动的服务name,接下来就看launchar服务是如何启动一个服务的.
    launcher服务收到消息后,就去处理,调用launcher.lua中的launch_service()方法

    local function launch_service(service,...)
    	local param = table.concat({...}, " ")
    	local inst = skynet.launch(service,param) --启动服务
    	local response = skynet.response()
    	if inst then
    		services[inst] = service .. " " .. param --保存服务名 参数
    		instance[inst] = response --保存闭包
    	else
    		reponse(false) -- 启动失败,抛出异常
    		return 	
    	end
    	return inst 
    end
    

    这里调用manager.lua中的sknet.launch方法

    function skynet.launch(...)
    	local addr = c.command("LAUNCH", table.concat({...}," "))
    	if addr then
    		return tonumber("0x" .. string.sub(addr,2))
    	end
    end
    

    这里则用调用到lua-skynet.c中的luaopen_skynet_core对应的方法 command字段对应lcommand方法

    static int lcommand(lua_State* L) {
    	struct skynet_context* context = lua_touserdata(L,lua_upvalueindex(1));
    	const char* cmd = luaL_checkstring(L,1); //取出命令
    	const char* parm = NULL; //参数
    	if (lua_gettop(L) == 2) { //传入的参数有2个
    		parm = luaL_checkstring(L,2); //取出参数串
    	}
    	result = skynet_command(context,cmd,parm); //执行命令
    	if (result) {
    		lua_pushstring(L,result); //压入返回值
    		return 1; //有一个返回值
    	}
    	return 0; //没有返回值
    }
    

    这里调到skynet_server.c中的skynet_command()方法,改方法通过字段名执行不同的方法

     static struct command_func cmd_funcs[] = { 
         { "TIMEOUT", cmd_timeout },
         { "REG", cmd_reg },
         { "QUERY", cmd_query },
         { "NAME", cmd_name },
         { "EXIT", cmd_exit },
         { "KILL", cmd_kill },
         { "LAUNCH", cmd_launch },
         { "GETENV", cmd_getenv },
         { "SETENV", cmd_setenv },
         { "STARTTIME", cmd_starttime },
         { "ABORT", cmd_abort },
         { "MONITOR", cmd_monitor },
         { "STAT", cmd_stat },
         { "LOGON", cmd_logon },
         { "LOGOFF", cmd_logoff },
         { "SIGNAL", cmd_signal },
         { NULL, NULL },
     };
    
    const char* 
    skynet_command(struct skynet_context* context, const char* cmd, const char* param) {
    	struct command_func * method = &cmd_funcs[0];
    	while(method->name) {
    		if (strcmp(cmd,method->name) == 0 ) {
    			return method->func(context,param);
    		}
    		++method;
    	}
    	return NULL;
    }
    

    根据传入的LAUNCHER参数,得知对应的方法为skynet_server.c 中的 cmd_launch,

    static const char* cmd_launch(struct skynet_context* context,const char* param) {
    	size_t sz = strlen(param);
    	char tmp[sz+1];
    	strcpy(tmp,param);
    	char* args = tmp;
    	char* mod = strsep(&args," \t\r\n"); //模块名
    	args = strsep(&args, "\r\n"); //参数
    	struct skynet_context* inst = skynet_context_new(mod,args); //创建服务
    	if (inst == NULL) {
    		return NULL;
    	}else{
    		id_to_hex(context->result,inst->handle); //转换十六进制
    		return context->result; //返回字符串(句柄的十六进制)
    	}
    }
    

    到这里,就是调用最开始的skynet_context_new()方法来创建一个服务

    展开全文
  • skynet怎么启动lua文件

    千次阅读 2018-03-29 11:38:12
    bootstrap.lua文件会执行skynet.start(func),这里会启动各种lua服务,调用各种lua文件。自此整个服务就跑起来了,逻辑只需要在lua里完成。 我们通过上面的分析,还可以得到如下的结论,luaservice配置变量路径是...

    前篇在skynet主体流程中说到,在slua服务初始化的时候会给自己的消息队列发送一条消息,内容为bootstrap。当消息被捕获并执行时,会调用slua的回调函数_launch,他是在模块初始化中指定的。我们来看看这个回调函数:

    static int
    _launch(struct skynet_context * context, void *ud, int type, int session, uint32_t source , const void * msg, size_t sz) {
    	assert(type == 0 && session == 0);
    	struct snlua *l = ud;
    	skynet_callback(context, NULL, NULL);
    	int err = _init(l, context, msg, sz);
    	if (err) {
    		skynet_command(context, "EXIT", NULL);
    	}
    
    	return 0;
    }

     

    注意到他再次将回调函数设为NULL了,不用担心,后面还会设置的。然后就是调用_init函数,在_init函数中有slua实例l,他是如何得到的呢?原来在slua服务的初始化设置回调函数的时候就与ctx绑定了。获取消息的时候通过handle找到ctx,然后就可以找到ctx对应的实例了。slua实例中有个lua虚拟机对象,这个是在服务的create函数中创建的。_init函数代码如下:

     

    static int
    _init(struct snlua *l, struct skynet_context *ctx, const char * args, size_t sz) {
    	lua_State *L = l->L;
    	l->ctx = ctx;
    	lua_gc(L, LUA_GCSTOP, 0);
    	lua_pushboolean(L, 1);  /* signal for libraries to ignore env. vars. */
    	lua_setfield(L, LUA_REGISTRYINDEX, "LUA_NOENV");
    	luaL_openlibs(L);
    	lua_pushlightuserdata(L, ctx);
    	lua_setfield(L, LUA_REGISTRYINDEX, "skynet_context");
    	luaL_requiref(L, "skynet.codecache", codecache , 0);
    	lua_pop(L,1);
    
    	const char *path = optstring(ctx, "lua_path","./lualib/?.lua;./lualib/?/init.lua");
    	lua_pushstring(L, path);
    	lua_setglobal(L, "LUA_PATH");
    	const char *cpath = optstring(ctx, "lua_cpath","./luaclib/?.so");
    	lua_pushstring(L, cpath);
    	lua_setglobal(L, "LUA_CPATH");
    	const char *service = optstring(ctx, "luaservice", "./service/?.lua");
    	lua_pushstring(L, service);
    	lua_setglobal(L, "LUA_SERVICE");
    	const char *preload = skynet_command(ctx, "GETENV", "preload");
    	lua_pushstring(L, preload);
    	lua_setglobal(L, "LUA_PRELOAD");
    
    	lua_pushcfunction(L, traceback);
    	assert(lua_gettop(L) == 1);
    
    	const char * loader = optstring(ctx, "lualoader", "./lualib/loader.lua");
    
    	int r = luaL_loadfile(L,loader);
    	if (r != LUA_OK) {
    		skynet_error(ctx, "Can't load %s : %s", loader, lua_tostring(L, -1));
    		_report_launcher_error(ctx);
    		return 1;
    	}
    	lua_pushlstring(L, args, sz);
    	r = lua_pcall(L,1,0,1);
    	if (r != LUA_OK) {
    		skynet_error(ctx, "lua loader error : %s", lua_tostring(L, -1));
    		_report_launcher_error(ctx);
    		return 1;
    	}
    	lua_settop(L,0);
    
    	lua_gc(L, LUA_GCRESTART, 0);
    
    	return 0;
    }

    这段代码主要是与lua交互,比较重要的是将当前ctx保存在slua实例对应的lua虚拟机中,后面的交互会用到。然后是从全局配置的lua虚拟机中获取相应的配置赋值给slua实例的虚拟机。因为lua虚拟机要知道去哪里寻找将执行的代码。

    接着就是执行'./lualib/loader.lua',参数为bootstrap,我们转向这个文件:

    local args = {}
    for word in string.gmatch(..., "%S+") do     --这里... 为bootstrap
    	table.insert(args, word)
    end
    
    SERVICE_NAME = args[1]     --bootstrap
    
    local main, pattern
    
    local err = {}
    for pat in string.gmatch(LUA_SERVICE, "([^;]+);*") do     --在lua_service变量中查找bootstrap.lua这个文件
    	local filename = string.gsub(pat, "?", SERVICE_NAME)
    	local f, msg = loadfile(filename)
    	if not f then
    		table.insert(err, msg)
    	else
    		pattern = pat
    		main = f
    		break
    	end
    end
    
    if not main then    --在lua_service变量模式中都没有找到bootstrap.lua文件则把所有错误都打印出来
    	error(table.concat(err, "\n"))
    end
    
    LUA_SERVICE = nil    --这个全局变量以后就没有用了
    package.path , LUA_PATH = LUA_PATH    --用LUA_PATH来取代内部变量package.path,然后自己为nil
    package.cpath , LUA_CPATH = LUA_CPATH  --同上
    
    local service_path = string.match(pattern, "(.*/)[^/?]+$")
    
    if service_path then
    	service_path = string.gsub(service_path, "?", args[1])
    	package.path = service_path .. "?.lua;" .. package.path
    	SERVICE_PATH = service_path
    else
    	local p = string.match(pattern, "(.*/).+$")
    	SERVICE_PATH = p    --只在snax中用过
    end
    
    if LUA_PRELOAD then
    	local f = assert(loadfile(LUA_PRELOAD))
    	f(table.unpack(args))
    	LUA_PRELOAD = nil
    end
    
    main(select(2, table.unpack(args)))  --talbe.unpack({1,2,3})展开为1,2,3。 select(2, 
     1,2,3)得到的是(2,3)即除了文件名的参数
    

    首先他以空格分隔出传入的参数,上边为'bootstrap',然后根据LUA_SERVICE找到并合成文件名,然后执行。如果bootstrap后有参数,参数将会传给文件执行,select(2, table.unpack(args))将得到所有除了文件名之外的参数。

    bootstrap.lua文件会执行skynet.start(func),这里会启动各种lua服务,调用各种lua文件。自此整个服务就跑起来了,逻辑只需要在lua里完成。

    我们通过上面的分析,还可以得到如下的结论,luaservice配置变量路径是为了寻找启动文件bootstrap = "snlua bootstrap" bootstrap.lua,之后则不起任何作用了。lua_path可能会替换掉package.path,而lua_cpath替换掉package.cpath,即lua内部require文件时的路径。


    关于这个skynet.start()的执行过程,以及lua层是怎么与消息交互的,这个下篇再讲。

     

    欢迎加入QQ群 858791125 讨论skynet,游戏后台开发,lua脚本语言等问题。

    展开全文
  • Dolphin Lua Core + TAStudio(自定义Dolphin构建) 该项目在Dolphin Emulator的修订版5.0中添加了Lua支持和TAStudio接口。 Lua API基于Dragonbane0的Zelda Edition,可在找到。 Lua核心 运行脚本 要运行已经实施的...
  • Lua到Rust FFI代码生成 激励榜样 锈 #[derive(LuaMarshalling)] pub struct A { string: String , integer: i32 , } pub mod extern_ffi { pub fn make_a (string: & str , integer: i32 ) -> A { A { string: ...
  • 今天工作需要在c程序中启动lua 的脚本解释器,并且运行三个lua的脚本文件(两个是配置文件,用户不可见存放全局变量,一个是主程序)今天用到的主要是 HWND this_window = GetActiveWindow(); ShellExecute( ...

    今天工作需要在c程序中启动lua 的脚本解释器,并且运行三个lua的脚本文件(两个是配置文件,用户不可见存放全局变量,一个是主程序)今天用到的主要是

     HWND this_window =  GetActiveWindow();
    
    ShellExecute( 
    
                    this_window, 
    
                    "open",  
    
                    execPath.c_str(),   //此处可能存在中文路径解析问题
    
                    execParams.c_str(),                 
    
                    prj_path.c_str(),
    
                    SW_SHOW            //
    
                );
    ShellExecute(
    hWnd: HWND; {指定父窗口句柄}
    Operation: PChar; {指定动作, 譬如: open、runas、print、edit、explore、find [2]  }
    FileName: PChar; {指定要打开的文件或程序}
    Parameters: PChar; {给要打开的程序指定参数; 如果打开的是文件这里应该是 nil}
    Directory: PChar; {缺省目录}
    ShowCmd: Integer {打开选项}
    ): HINST;

    最后的参数是 :

    SW_HIDE 隐藏窗口,活动状态给令一个窗口
    SW_MINIMIZE 最小化窗口,活动状态给令一个窗口
    SW_RESTORE 用原来的大小和位置显示一个窗口,同时令其进入活动状态
    SW_SHOW 用当前的大小和位置显示一个窗口,同时令其进入活动状态
    SW_SHOWMAXIMIZED 最大化窗口,并将其激活
    SW_SHOWMINIMIZED 最小化窗口,并将其激活
    SW_SHOWMINNOACTIVE 最小化一个窗口,同时不改变活动窗口
    SW_SHOWNA 用当前的大小和位置显示一个窗口,不改变活动窗口
    SW_SHOWNOACTIVATE 用最近的大小和位置显示一个窗口,同时不改变活动窗口
    SW_SHOWNORMAL 与SW_RESTORE相同

    也就是你的运行模式,前期开发肯定是想看到打印信息的,后期实际使用肯定是隐藏的。

    lua.exe 提供了以下几种方法

    usage: lua [options] [script [args]]
    Available options are:
      -e stat  execute string 'stat'
      -i       enter interactive mode after executing 'script'
      -l name  require library 'name'
      -v       show version information
      -E       ignore environment variables
      --       stop handling options
      -        stop handling options and execute stdin

    我们使用的就是-l  这个选项,例如我们需要执行 config.lua global.lua 和mainfunc.lua 

    那我们们的execparams 就是 -lconfig -lglobal -lmainfunc 

    这三个文件最好是在同样的路径下,在ShellExecute 中可以加入一个执行路径的参数,可以定位找到一个路径(我测试过 在-l的参数之后添加 绝对路径  windows下失败了,而且对于   a.b.lua 的文件    -la.b   也是行不通的!)

    展开全文
  • 如何启动一个lua服务

    2021-05-14 15:34:41
    最近在看公司项目的代码,发现了一个问题。 skynet.newservice(“xxx”); 写的是xxx, 是一个目录的名字,而目录名下面有一个main.lua。...每个skynet进程在启动时,都会启动一个lua层的launcher服务,该服务

    skynet.newservice(“xxx”); 写的是xxx, 是一个目录的名字,而目录名下面有一个main.lua。 启动的正是这个main的脚本。
    因为在之前skynet api的学习中, skynet.newservice,传入的的参数都是要启动的服务的脚本名字的。那为啥项目里传入的参数是目录名了。
    带着这个问题,有必要深入地去看一下skynet 是如何启动一个lua服务的。

    每个skynet进程在启动时,都会启动一个lua层的launcher服务,该服务主要负责skynet运作期间,服务的创建工作。

    其他的lua服务都是需要有 launcher服务来创建的。

    我们在lua层创建一个lua层服务时,通常会调用skynet.newservice函数。

    展开全文
  • skynet如何启动一个lua服务

    千次阅读 2018-02-27 11:20:24
    skynet是如何启动一个lua语言编写的服务的的呢?skynet服务,在skynet框架中,具体是以什么形式存在的呢?  每个skynet进程在启动时,都会启动一个lua层的launcher服务,该服务主要负责skynet运作期间,服务的...
  • rust-lua版权所有2014 Lily Ballard说明这是一组与Lua 5.1的Rust绑定。 目标是为Lu rust-lua提供(相对)安全的接口版权所有2014 Lily Ballard描述这是一组与Lua 5.1的Rust绑定。 目的是为Lua提供一个(相对)安全的...
  • 前言:之前从Skynet启动过程,解读了skynet的启动部分C语言编写的底层源码,最后成功启动了引导的lua服务bootstrap.lua,接下来我们要尝试自定义一个lua服务,并让它启动起来。bootstrap实现功能:bootstrap.lua源码...
  • 1.下载包[root@dev~]#wgethttp://www.lua.org/ftp/lua-5.2.0.tar.gz2.解压缩[root@devlua]#tarzxflua-5.2.0.tar.gz3.修改Makefile文件[root@devlua]#cdlua-5.2.0[root@devlua-5.2.0]#vimMakefileINSTALL_TOP=/us...
  • launchmode,启动lua.exe来执行你的代码。 程序,lua.exe执行的入口文件 cwd,lua.exe的当前目录 stopOnEntry,开始调试时是否先暂停 luaexe,指定lua exe的路径,如果不填则由luaVersion和luaArch决定 luaVersion...
  • Cocos2dx lua 启动流程

    千次阅读 2016-06-15 18:39:54
    但是VS2013在C++下是看不到lua的逻辑代码的,这个时候就需要新建一个VS2013的lua项目了,LUA->New Lua Porject,可以看到新建VS的lua项目需要的设置: 4.关于创建VS lua项目的参数 Lua scripts folder:项目...
  • 路 Rust Lua 虚拟机
  • python执行lua代码

    2020-12-07 11:35:58
    楔子下面我们来看看如何使用python来执行lua代码。如果了解lua的话,可能会感到器官,我们之前调用C、调用go,都是调用其编写的动态库。可lua是脚本语言啊,难道也可以写动态库吗?其实我们不是调用动态库,而是直接...
  • idea进行lua开发及运行nginx-lua程序

    千次阅读 2019-05-21 19:55:27
    由于openresty每次在启动nginx时都需要通过命令重启比较麻烦,因此打算通过idea运行nginx服务,且idea插件对代码提示有一定程度的支持。 一、安装lua插件 Idea开发lua需要安装EmmyLua插件,在Plugins中搜索EmmyLua...
  • 从Python运行Lua脚本

    千次阅读 2020-12-24 11:49:32
    假设我有一个包含2个函数的Lua脚本.我想用Python脚本中的一些参数调用这些函数中的每一个.我已经看过如何使用Lunatic Python在Python中嵌入Lua代码的教程,反之亦然,但是,我在Python脚本中执行的Lua函数不是静态的,...
  • lua reload lua脚步重启热更

    千次阅读 2017-03-14 16:55:21
    --本项目是以 main.lua 为主文件,也可以指定加载某个文件 recursive_reload( "main", 0 ) --recursive_reload("baseClass.BaseClass", 0) print( "[reload_script_files...done]") return "reload ok" end ...
  • scite 3.0.2 + 的 Lua 启动脚本和用户选项文件。 所有文件都在 Linux mint 13 下测试,应解压到主目录 ~/. 主要特点: 智能标签 lua 中的简单组织模式 用于突出显示组织文件的 lua 词法分析器
  • VSCode 运行 Lua代码

    千次阅读 2019-12-11 20:38:21
    1. 安装lua-5.3.5_Win64 地址:http://joedf.ahkscript.org/LuaBuilds/ 解压至 如下路劲 2. 添加环境变量 ...安装Lua 5.3 Debug 插件,可以在vscode中按Ctrl+P,输入 ext install lua-debug ...
  • lua脚本传参数

    千次阅读 2020-02-04 16:51:06
  • 这里主要介绍两种加载途径,一个是从本地加载AB包,另一个是从服务器端加载AB包和Lua脚本  从本地文件加载:(resName代表预设体的名字,filePath是预设体的名字)  void LoadResource(string resName, string ...
  • title: unity-lua运行时重载重启 categories: Unity3d tags: [unity, lua, runtime, reload, restart] date: 2020-06-30 11:20:08 comments: false mathjax: true
  • LuaJava:跟着LuaJava一步一步学习JNI -1

    千次阅读 2015-10-25 22:45:35
    LuaJava:跟着LuaJava一步一步学习JNI -1
  • xLua笔记(1)—Lua启动类 前言 本笔记是为了学习用xlua写unity游戏而制作的笔记,作为自己加深对于知识的理解和记忆有感而发。如果错误,恳请各位大神回复纠正,谢谢 本教程是基于xLua的,至于xLua的教程这里我就不...
  • Lua 在Windows下的运行环境搭建

    万次阅读 2018-08-06 23:46:24
    掌握lua语言,搭建在Windows下的开发调试环境,安装Lua For Windows这套工具。 &lt;一.下载并且安装:&gt; Lua For Windows 的官方网站:(推荐5.1) http://code.google.com/p/luaforwindows/ 双击LuaFor...
  • 解决VS code不能运行lua的方法

    千次阅读 2019-07-09 13:39:06
    如果你的编写环境和DEBUG环境都安装好了,就是VS中的一些插件,(如果没有安装或者不会的话,网上很多的,搜一下) 但是没有教你怎么运行的,这就难受了(或者是配置什么变量才能运行的) 很简单,再安装一个运行...
  • Lua 协同程序(coroutine)与线程比较类似:拥有独立的堆栈,独立的局部变量,独立的指令指针,同时又与其它协同程序共享全局变量和其它大部分东西。协同是非常强大的功能,但是用起来也很复杂。 线程和协同程序区别 ...
  • 在eclipse中建立lua开发环境

    千次阅读 2018-03-25 21:23:35
    在Eclipse中开发lua代码LuaEclipse 是 Eclipse 用来开发 Lua 程序的插件,功能比较完备,它可以实现编Lua脚本代码、语法高亮、编译错误提示,代码和注释的折叠、调试等。LuaEclipse:...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 43,947
精华内容 17,578
关键字:

如何启动lua