首页 数据库 mysql教程 cocos2dx lua文件的加载问题

cocos2dx lua文件的加载问题

Jun 07, 2016 pm 03:49 PM
lua 函数 加载 文件 问题

lua库函数里面自带有加载lua文件的几个函数 static const lua_CFunction package_loaders[] = { lj_cf_package_loader_preload, lj_cf_package_loader_lua, lj_cf_package_loader_c, lj_cf_package_loader_croot, NULL }; 在lua的源码lib_package.c文件可以

lua库函数里面自带有加载lua文件的几个函数

static const lua_CFunction package_loaders[] =

{
  lj_cf_package_loader_preload,
  lj_cf_package_loader_lua,
  lj_cf_package_loader_c,
  lj_cf_package_loader_croot,
  NULL

};  

在lua的源码lib_package.c文件可以找到。其中还包含了一个初始化函数

LUALIB_API int luaopen_package(lua_State *L)
{
  int i;
  int noenv;
  luaL_newmetatable(L, "_LOADLIB");
  lj_lib_pushcf(L, lj_cf_package_unloadlib, 1);
  lua_setfield(L, -2, "__gc");
  luaL_register(L, LUA_LOADLIBNAME, package_lib);
  lua_pushvalue(L, -1);
  lua_replace(L, LUA_ENVIRONINDEX);
  lua_createtable(L, sizeof(package_loaders)/sizeof(package_loaders[0])-1, 0);
  for (i = 0; package_loaders[i] != NULL; i++) {
    lj_lib_pushcf(L, package_loaders[i], 1);
    lua_rawseti(L, -2, i+1);
  }
  lua_setfield(L, -2, "loaders");
  lua_getfield(L, LUA_REGISTRYINDEX, "LUA_NOENV");
  noenv = lua_toboolean(L, -1);
  lua_pop(L, 1);
  setpath(L, "path", LUA_PATH, LUA_PATH_DEFAULT, noenv);
  setpath(L, "cpath", LUA_CPATH, LUA_CPATH_DEFAULT, noenv);
  lua_pushliteral(L, LUA_PATH_CONFIG);
  lua_setfield(L, -2, "config");
  luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 16);
  lua_setfield(L, -2, "loaded");
  luaL_findtable(L, LUA_REGISTRYINDEX, "_PRELOAD", 4);
  lua_setfield(L, -2, "preload");
  lua_pushvalue(L, LUA_GLOBALSINDEX);
  luaL_register(L, NULL, package_global);
  lua_pop(L, 1);
  return 1;
}

这个函数会在lua打开所有库的时候调用(即 luaL_openlibs(m_state)时)。仔细看里面的代码会发现,package_loaders里面的所有函数都被存在package.loaders的全局表中。

cocos2dx官方在这个全局表里面增加了一个自己实现的加载函数,即Cocos2dxLuaLoader。具体实现可参看CCLuaStack.cpp文件。

void CCLuaStack::addLuaLoader(lua_CFunction func)
{
    if (!func) return;
    
    // stack content after the invoking of the function
    // get loader table
    lua_getglobal(m_state, "package");                                  /* L: package */
    lua_getfield(m_state, -1, "loaders");                               /* L: package, loaders */
    
    // insert loader into index 2
    lua_pushcfunction(m_state, func);                                   /* L: package, loaders, func */
    for (int i = lua_objlen(m_state, -2) + 1; i > 2; --i)
    {
        lua_rawgeti(m_state, -2, i - 1);                                /* L: package, loaders, func, function */
        // we call lua_rawgeti, so the loader table now is at -3
        lua_rawseti(m_state, -3, i);                                    /* L: package, loaders, func */
    }
    lua_rawseti(m_state, -2, 2);                                        /* L: package, loaders */
    
    // set loaders into package
    lua_setfield(m_state, -2, "loaders");                               /* L: package */
    
    lua_pop(m_state, 1);
}

这个函数将cocosdx自带的load函数存到了package.loaders表的第二个索引处。即插在  lj_cf_package_loader_preload和
  lj_cf_package_loader_lua之间。



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

介绍完上面这些背景之后,我们再看看实际加载过程中,require函数在android下面和win下面需求路径不同的问题。

在android环境中,require实际起作用的加载函数是官方自带的Cocos2dxLuaLoader函数,而且路径必须是相对assets下的完整路径。lua里面自带几个加载函数都会加载不到(具体原因不明,可能跟lua的相对路径不在assets下有关,即使加path路径也没用(原因是android下的lua文件是在APK压缩包里面去找,不存在绝对路径,所以lua会加载不到))。不相信的童鞋可以把CCLuaStack.cpp中的addLuaLoader注释掉,你会发现所有的require都找不到文件

在win环境中,可以通过addSearchPath的方式,在package.path里面增加lua文件的查找路径,由于添加的是绝对路径,所以你会发现就算你require里面没填完整路径,lua也会自动在path里去找相关的文件进行加载。(但是Cocos2dxLuaLoader这个函数其实不能正常加载,所以你可能会看到,log里面显示没加载到,实际已经加载成功的现象。这里加载成功是lua自带的加载函数实现的)

结论:

        尽量都用assets下的完整路径,这样Cocos2dxLuaLoader都会加载的到,不会出现误提示。win下可以用addSearchPath的方式,android下不能用

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门文章

仓库:如何复兴队友
3 周前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.能量晶体解释及其做什么(黄色晶体)
1 周前 By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island冒险:如何获得巨型种子
3 周前 By 尊渡假赌尊渡假赌尊渡假赌

热门文章

仓库:如何复兴队友
3 周前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.能量晶体解释及其做什么(黄色晶体)
1 周前 By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island冒险:如何获得巨型种子
3 周前 By 尊渡假赌尊渡假赌尊渡假赌

热门文章标签

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

golang函数动态创建新函数的技巧 golang函数动态创建新函数的技巧 Apr 25, 2024 pm 02:39 PM

golang函数动态创建新函数的技巧

C++ 函数命名中参数顺序的考虑 C++ 函数命名中参数顺序的考虑 Apr 24, 2024 pm 04:21 PM

C++ 函数命名中参数顺序的考虑

如何在Java中写出高效和可维护的函数? 如何在Java中写出高效和可维护的函数? Apr 24, 2024 am 11:33 AM

如何在Java中写出高效和可维护的函数?

C++ 函数默认参数与可变参数的优缺点比较 C++ 函数默认参数与可变参数的优缺点比较 Apr 21, 2024 am 10:21 AM

C++ 函数默认参数与可变参数的优缺点比较

excel函数公式大全 excel函数公式大全 May 07, 2024 pm 12:04 PM

excel函数公式大全

C++ 函数返回引用类型有什么好处? C++ 函数返回引用类型有什么好处? Apr 20, 2024 pm 09:12 PM

C++ 函数返回引用类型有什么好处?

C++ 函数中引用参数和指针参数的高级用法 C++ 函数中引用参数和指针参数的高级用法 Apr 21, 2024 am 09:39 AM

C++ 函数中引用参数和指针参数的高级用法

C++ 函数异常进阶:定制错误处理 C++ 函数异常进阶:定制错误处理 May 01, 2024 pm 06:39 PM

C++ 函数异常进阶:定制错误处理

See all articles