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