Operating Environment
Win7 64
cocos2d-2.1rc0-x-2.1.2
LUA 5.1
Usually we write good LUA code is clear form, anyone can see the changes, in order to prevent their labor results are not easily stolen by others, you can use LUAC (LUA library) to encrypt it, converted to binary files. This will not allow the LUA code to be viewed directly, but there is a problem: it works well under windows and is black on Android, prompting for errors:
[LUA ERROR] binary string:unexpected end in precompiled chunk
Traced
View the LUA load code in BOOL Appdelegate::applicationdidfinishlaunching ():
#if (Cc_target_platform = = cc_platform_android) ccstring* pstrfilecontent = Ccstring::createwithcontentsoffile (" Program/main.lua "); if (pstrfilecontent) { pengine->executestring (pstrfilecontent->getcstring ()); } #else std::string Path = Ccfileutils::sharedfileutils ()->fullpathforfilename ("Program/main.lua"); Pengine->addsearchpath (path.substr (0, path.find_last_of ("/")). C_str ()); Pengine->executescriptfile (Path.c_str ()); #endif
Here executestring () loads LUA files and continues to see what the source of the real work is:
LUALIB_API int Lual_loadbuffer (lua_state *l, const char *buff, size_t size, const char *name) { LoadS ls; LS.S = buff; ls.size = size; Return Lua_load (L, GetS, &ls, name);}
Look back at the execution of the function executescriptfile ():
LUALIB_API int Lual_loadfile (lua_state *l, const char *filename) {LOADF lf; int status, Readstatus; int C; int fnameindex = Lua_gettop (L) + 1; /* Index of filename on the stack */lf.extraline = 0; if (filename = = NULL) {lua_pushliteral (L, "=stdin"); LF.F = stdin; } else {lua_pushfstring (L, "@%s", filename); LF.F = fopen (filename, "R"); if (lf.f = = NULL) return Errfile (L, "open", Fnameindex); } c = Getc (LF.F); if (c = = ' # ') {/* Unix exec. File */lf.extraline = 1; while ((c = getc (LF.F))! = EOF && c! = ' \ n '); /* Skip First line */if (c = = ' \ n ') c = getc (LF.F); } if (c = = lua_signature[0] && filename) {/* binary file? */lf.f = freopen (filename, "RB", LF.F); /* Reopen in binary mode */if (LF.F = = NULL) return Errfile (L, "reopen", Fnameindex); /* Skip eventual ' #!... ' * * while ((c = getc (LF.F))! = EOF && c! = lua_signature[0]); Lf.extraline = 0; } ungetc (c, LF.F); Status = Lua_load (L, GETF, & LF, lua_tostring (L,-1)); The key, as in Lual_loadbuffer () Readstatus = Ferror (LF.F); if (filename) fclose (LF.F); /* Close file (even in case of errors) */if (readstatus) {lua_settop (L, Fnameindex); /* Ignore results from ' lua_load ' */return Errfile (L, "read", Fnameindex); } lua_remove (L, Fnameindex); return status;}
Note The Chinese comment section of the code, which explains why files compiled with LUAC can be run well under Windows (iOS is OK), but not on Android. Lual_loadfile () Determines whether LUA files are encrypted by c = = Lua_signature[0], and if so, re-opens in "RB" mode.
Solutions
Modify the Loader_android () function in Scripting\lua\cocos2dx_support\cocos2dxlualoader.cpp
Before modification:
int loader_android (lua_state *l) { std::string filename (lual_checkstring (L, 1)); Filename.append (". Lua"); ccstring* pfilecontent = Ccstring::createwithcontentsoffile (Filename.c_str ()); if (pfilecontent) { if (lual_loadstring (L, pfilecontent->getcstring ())! = 0) { lual_error (L, " Error loading module%s from file%s: \n\t%s ", lua_tostring (L, 1), Filename.c_str (), lua_tostring (L,-1)); } } else { Cclog ("Can not get file data of%s", Filename.c_str ()); } return 1; }
After modification:
int loader_android (lua_state* L) {unsigned char* pData = nullptr;unsigned long size = 0;/* Modify for read Lua script from Bytecode */std::string filename (lual_checkstring (L, 1)), std::string rel_name = Filename.append (". Lua");pD ATA = Ccfileutils::sharedfileutils ()->getfiledata (Rel_name.c_str (), "RB", &size), if (PData) {if (Lual_loadbuffer (L , (char*) pdata,size,rel_name.c_str ())! = 0) {lual_error (L, "error loading module s from File S:s", Lua_tostring (L, 1), RE L_name.c_str (), lua_tostring (L,-1));}} else {Cclog ("Can not get file data of%s", Filename.c_str ());} Cc_safe_delete_array (PData); return 1;}
Also, since the first time that LUA is loaded in CPP does not call Loader_android (), this is because Ual_loadbuffer only loads the file into a chunk and does not run the chunk, so add a tune to the name Lua_pcall, As follows:
int loader_android (lua_state* L) {unsigned char* pData = nullptr;unsigned long size = 0;/* Modify for read Lua script from Bytecode */std::string filename (lual_checkstring (L, 1)), std::string rel_name = Filename.append (". Lua");pD ATA = Ccfileutils::sharedfileutils ()->getfiledata (Rel_name.c_str (), "RB", &size), if (PData) {if (Lual_loadbuffer (L , (char*) pdata,size,rel_name.c_str ())! = 0 | | Lua_pcall (l, 0, Lua_multret, 0)) {//Modify place Lual_error (L, "error loading module s from File S:s", Lua_tostring (L, 1), Rel_na Me.c_str (), lua_tostring (L,-1));}} else {Cclog ("Can not get file data of%s", Filename.c_str ());} Cc_safe_delete_array (PData); return 1;}
Or we could steal a chicken,
Pengine->executestring ("Require \" program/main\ ""); Note that the \ "
The last of our appdelegate::applicationdidfinishlaunching () is probably like this,
Const char* Luafile = "Program/main.lua"; #if (cc_target_platform = = cc_platform_android) std::string path = CCFileUtils:: Sharedfileutils ()->fullpathforfilename (luafile); Cclog ("Path =%s", Path.c_str ()), std::string subpath = path.substr (0, path.find_last_of ("/")); Cclog ("Sub path =%s", Subpath.c_str ());p Engine->addsearchpath (Subpath.c_str ());std::vector<std::string> Searchpaths = Ccfileutils::sharedfileutils ()->getsearchpaths () Searchpaths.insert (SearchPaths.begin (), SubPath ); Ccfileutils::sharedfileutils ()->setsearchpaths (searchpaths);p engine->executestring ("Require \" program/ Main\ ""); Note here the \ "#else std::string Path = Ccfileutils::sharedfileutils ()->fullpathforfilename (luafile); Pengine->addsearchpath (path.substr (0, path.find_last_of ("/")). C_str ()); Pengine->executescriptfile (Path.c_str ()); #endif
Note: Here the author stole the chicken a bit.
Reference reference
http://www.cocos2d-x.org/forums/11/topics/28628
Http://www.cnblogs.com/mrblue/archive/2013/06/06/3122543.html