tryRequireClib("libpdebug"
hookLib = require(libName)
if hookLib ~= nil then -- 发现是因为没有hookLib导致的断点无法同步功能 hookLib.sync_breakpoints(); end
useCHook 控制的
launch.json配置下
-- [LUA-print] x86Path:e:\proj\LuaHelper\luahelper-vscode/debugger/debugger_lib/plugins/win/x86/501/?.dll; -- [LUA-print] x64Path:e:\proj\LuaHelper\luahelper-vscode/debugger/debugger_lib/plugins/win/x86_64/501/?.dll; 会尝试加载这2个路径下的libpdebug,如果位数不符合,会加载失败,直到找到正确的位置,所以这里的加载会成功,虽然cocos2dx插入了自己的loader,cocos2dx-loader会提示can not get file data of,但是会继续通过下个loader继续加载dll,这样也能保证dll被正常加载。 找了好久,找错了方向,不过也了解到很多细节 local clibExt, platform; if OSType == "Darwin" then clibExt = "/?.so;"; platform = "mac"; elseif OSType == "Linux" then clibExt = "/?.so;"; platform = "linux"; else clibExt = "/?.dll;"; platform = "win"; end -- 为啥是/?.dll local x86Path = clibPath.. platform .."/x86/".. lua_ver .. clibExt; local x64Path = clibPath.. platform .."/x86_64/".. lua_ver .. clibExt; tryRequireClib("libpdebug", x64Path) or this.tryRequireClib("libpdebug", x86Path ---*:.\?.dll; -- E:\proj\tank5\client\?.dll; --E:\proj\tank5\client\loadall.dll; --e:\proj\LuaHelper\luahelper-vscode/debugger/debugger_lib/plugins/win/x86_64/501/?.dll; package.cpath package.cpath = package.cpath .. ';' .. libPath; local status, err = pcall(function() hookLib = require(libName) end); -- 这里会require c lib
在Lua中,package.cpath
是一个全局变量,用于指定C模块的加载路径。C模块是使用C语言编写的Lua扩展,可以通过require
函数加载并在Lua中使用。
package.cpath
的值是一个字符串,其中包含一系列模块文件的搜索路径。每个路径之间使用分号(;)分隔。当Lua解释器在执行require
函数时,会遍历这些路径,并尝试找到对应的C模块文件进行加载。
can not get file data of E:\proj\tank5\client\lua?\init.lua;libpdebug.lua
是cocos重写require导致找不到lib,路径刚好对着
cocos2dx将自己的loader插入到位置2,其他的默认loader都往后移动了
void LuaStack::addLuaLoader(lua_CFunction func) { if (!func) return; // stack content after the invoking of the function // get loader table lua_getglobal(_state, "package"); /* L: package */ lua_getfield(_state, -1, "loaders"); /* L: package, loaders */ // insert loader into index 2 lua_pushcfunction(_state, func); /* L: package, loaders, func */ for (int i = (int)(lua_objlen(_state, -2) + 1); i > 2; --i) { lua_rawgeti(_state, -2, i - 1); /* L: package, loaders, func, function */ // we call lua_rawgeti, so the loader table now is at -3 lua_rawseti(_state, -3, i); /* L: package, loaders, func */ } lua_rawseti(_state, -2, 2); /* L: package, loaders */ // set loaders into package lua_setfield(_state, -2, "loaders"); /* L: package */ lua_pop(_state, 1); }
这里面牵扯c++和lua交互的问题,我的lua学习代码仓库
lua的实现
- packages
LUAMOD_API int luaopen_package (lua_State *L) { createclibstable(L); luaL_newlib(L, pk_funcs); /* create 'package' table */ createsearcherstable(L); /* set paths */ setpath(L, "path", LUA_PATH_VAR, LUA_PATH_DEFAULT); setpath(L, "cpath", LUA_CPATH_VAR, LUA_CPATH_DEFAULT); /* store config information */ lua_pushliteral(L, LUA_DIRSEP "\n" LUA_PATH_SEP "\n" LUA_PATH_MARK "\n" LUA_EXEC_DIR "\n" LUA_IGMARK "\n"); lua_setfield(L, -2, "config"); /* set field 'loaded' */ luaL_getsubtable(L, LUA_REGISTRYINDEX, LUA_LOADED_TABLE); lua_setfield(L, -2, "loaded"); /* set field 'preload' */ luaL_getsubtable(L, LUA_REGISTRYINDEX, LUA_PRELOAD_TABLE); lua_setfield(L, -2, "preload"); lua_pushglobaltable(L); lua_pushvalue(L, -2); /* set 'package' as upvalue for next lib */ luaL_setfuncs(L, ll_funcs, 1); /* open lib into global table */ lua_pop(L, 1); /* pop global table */ return 1; /* return 'package' table */ }
- require
static int ll_require (lua_State *L) { const char *name = luaL_checkstring(L, 1); lua_settop(L, 1); /* LOADED table will be at index 2 */ lua_getfield(L, LUA_REGISTRYINDEX, LUA_LOADED_TABLE); lua_getfield(L, 2, name); /* LOADED[name] */ if (lua_toboolean(L, -1)) /* is it there? */ return 1; /* package is already loaded */ /* else must load package */ lua_pop(L, 1); /* remove 'getfield' result */ findloader(L, name); lua_rotate(L, -2, 1); /* function <-> loader data */ lua_pushvalue(L, 1); /* name is 1st argument to module loader */ lua_pushvalue(L, -3); /* loader data is 2nd argument */ /* stack: ...; loader data; loader function; mod. name; loader data */ lua_call(L, 2, 1); /* run loader to load module */ /* stack: ...; loader data; result from loader */ if (!lua_isnil(L, -1)) /* non-nil return? */ lua_setfield(L, 2, name); /* LOADED[name] = returned value */ else lua_pop(L, 1); /* pop nil */ if (lua_getfield(L, 2, name) == LUA_TNIL) { /* module set no value? */ lua_pushboolean(L, 1); /* use true as result */ lua_copy(L, -1, -2); /* replace loader result */ lua_setfield(L, 2, name); /* LOADED[name] = true */ } lua_rotate(L, -2, 1); /* loader data <-> module result */ return 2; /* return module result and loader data */ }
需要参考下cocos lua是怎么加载cjson这个库的,因为底层也是require的
error loading module 'libpdebug' from file 'e:/proj/LuaHelper/luahelper-vscode/debugger/debugger_lib/plugins/win/x86_64/501/libpdebug.dll': %1 不是有效的 Win32 应用程序。
注意加载的位数,不要混用不同位数的dll,如果exe是32位,但是require("64.dll")就会出现上边的问题。
lua.h中有
#define LUA_VERSION_NUM 501
如果lua是以源代码的方式编译到exe中,那么就无法正常加载c library