[√]luahelper为什么无法调试cocos2dx lua

简介: [√]luahelper为什么无法调试cocos2dx lua

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,路径刚好对着

image.png

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

目录
相关文章
|
11月前
[√]cocos2dx vld检测lua websocket的内存泄露问题
[√]cocos2dx vld检测lua websocket的内存泄露问题
65 0
cocos2dx 3.2之Lua打飞机项目
1          创建lua打飞机项目 cocos new T32Lua -dE:\Installed\cocos2d-x-3.2\cocos2d-x-3.2\projects -l lua 2  项目代码 Common.lua --用于打印日志信息 function cclog(...)     print(string.format(...)
1924 0
|
XML 数据格式
[cocos2dx lua] 打表工具
cocos2dx lua工程里常常要用到数值,数值策划将数据填写在一个个excel表格里面,但程序要用到数据是.lua格式的table,这时就要用到打表工具,这个工具是我的上司写的,具体的开发实现还没有研究,日后可以研究一下,但原理就是通过自己配置.table文件,本质是xml,这个文件跟excel一一对应,也就是.table文件指定了excel的格式。
1153 0
[cocos2dx lua]cocos2dx lua入门
最基本的层 [plain] view plaincopy function createInGameLayer()            local inGameLayer = cc.
1093 0
|
4月前
|
消息中间件 NoSQL Java
Redis系列学习文章分享---第六篇(Redis实战篇--Redis分布式锁+实现思路+误删问题+原子性+lua脚本+Redisson功能介绍+可重入锁+WatchDog机制+multiLock)
Redis系列学习文章分享---第六篇(Redis实战篇--Redis分布式锁+实现思路+误删问题+原子性+lua脚本+Redisson功能介绍+可重入锁+WatchDog机制+multiLock)
206 0