cocos2dx 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下不能用

Alat AI Hot

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool
Gambar buka pakaian secara percuma

Clothoff.io
Penyingkiran pakaian AI

AI Hentai Generator
Menjana ai hentai secara percuma.

Artikel Panas

Alat panas

Notepad++7.3.1
Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina
Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1
Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6
Alat pembangunan web visual

SublimeText3 versi Mac
Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Topik panas



Bahasa Go menyediakan dua teknologi penciptaan fungsi dinamik: penutupan dan refleksi. penutupan membenarkan akses kepada pembolehubah dalam skop penutupan, dan refleksi boleh mencipta fungsi baharu menggunakan fungsi FuncOf. Teknologi ini berguna dalam menyesuaikan penghala HTTP, melaksanakan sistem yang sangat boleh disesuaikan dan membina komponen boleh pasang.

Dalam penamaan fungsi C++, adalah penting untuk mempertimbangkan susunan parameter untuk meningkatkan kebolehbacaan, mengurangkan ralat dan memudahkan pemfaktoran semula. Konvensyen susunan parameter biasa termasuk: tindakan-objek, objek-tindakan, makna semantik dan pematuhan perpustakaan standard. Susunan optimum bergantung pada tujuan fungsi, jenis parameter, kemungkinan kekeliruan dan konvensyen bahasa.

Kunci untuk menulis fungsi Java yang cekap dan boleh diselenggara ialah: pastikan ia mudah. Gunakan penamaan yang bermakna. Mengendalikan situasi khas. Gunakan keterlihatan yang sesuai.

1. Fungsi SUM digunakan untuk menjumlahkan nombor dalam lajur atau sekumpulan sel, contohnya: =SUM(A1:J10). 2. Fungsi AVERAGE digunakan untuk mengira purata nombor dalam lajur atau sekumpulan sel, contohnya: =AVERAGE(A1:A10). 3. Fungsi COUNT, digunakan untuk mengira bilangan nombor atau teks dalam lajur atau sekumpulan sel, contohnya: =COUNT(A1:A10) 4. Fungsi IF, digunakan untuk membuat pertimbangan logik berdasarkan syarat yang ditentukan dan mengembalikan hasil yang sepadan.

Kelebihan parameter lalai dalam fungsi C++ termasuk memudahkan panggilan, meningkatkan kebolehbacaan dan mengelakkan ralat. Kelemahannya ialah fleksibiliti terhad dan sekatan penamaan. Kelebihan parameter variadic termasuk fleksibiliti tanpa had dan pengikatan dinamik. Kelemahan termasuk kerumitan yang lebih besar, penukaran jenis tersirat dan kesukaran dalam penyahpepijatan.

Faedah fungsi mengembalikan jenis rujukan dalam C++ termasuk: Peningkatan prestasi: Melewati rujukan mengelakkan penyalinan objek, sekali gus menjimatkan memori dan masa. Pengubahsuaian langsung: Pemanggil boleh mengubah suai secara langsung objek rujukan yang dikembalikan tanpa menugaskannya semula. Kesederhanaan kod: Lulus melalui rujukan memudahkan kod dan tidak memerlukan operasi penugasan tambahan.

Pengendalian pengecualian dalam C++ boleh dipertingkatkan melalui kelas pengecualian tersuai yang menyediakan mesej ralat khusus, maklumat kontekstual dan melaksanakan tindakan tersuai berdasarkan jenis ralat. Tentukan kelas pengecualian yang diwarisi daripada std::exception untuk memberikan maklumat ralat tertentu. Gunakan kata kunci lontaran untuk membuang pengecualian tersuai. Gunakan dynamic_cast dalam blok try-catch untuk menukar pengecualian yang ditangkap kepada jenis pengecualian tersuai. Dalam kes sebenar, fungsi open_file membuang pengecualian FileNotFoundException Menangkap dan mengendalikan pengecualian boleh memberikan mesej ralat yang lebih spesifik.

Perbezaan antara fungsi PHP tersuai dan fungsi yang dipratentukan ialah: Skop: Fungsi tersuai terhad kepada skop definisinya, manakala fungsi yang dipratentukan boleh diakses di seluruh skrip. Cara mentakrifkan: Fungsi tersuai ditakrifkan menggunakan kata kunci fungsi, manakala fungsi yang dipratakrifkan ditakrifkan oleh kernel PHP. Lulus parameter: Fungsi tersuai menerima parameter, manakala fungsi yang dipratentukan mungkin tidak memerlukan parameter. Kebolehlanjutan: Fungsi tersuai boleh dibuat mengikut keperluan, manakala fungsi yang dipratentukan terbina dalam dan tidak boleh diubah suai.
