首先书接上一遍,上一遍说到我们可以在c中获取Lua传递过来的Table,然后通过栈的操作,获取table中的字符或者number.
一切都那么的完美,所以我就把这段代码直接用于我们的工程中,构建,出包,安装,点击按钮,
一切都很顺利了吗?然后,并没有!
我发现,我在Lua中获取的table元素中的字符串全部消失了,而table中number元素的数据全部都在。这是为什么呢?
当字符串正在被访问的时候不要将其出栈;永远不要修改字符串。
所以我的栈都没有让字符串出栈,一直保留在栈内。
看一下代码:
//------------------------此时栈中的内容应该如下-------------------
// 说明 栈内容 排序 排序
// 栈低/栈顶 table -1 1
luaL_checktype(L, 1, LUA_TTABLE);//检查栈顶是否一个table
lua_pushnumber(L, 1);//先向栈中压入一个数字 为何要压入一个数字呢?
//------------------------此时栈中的内容应该如下-------------------
// 说明 栈内容 排序 排序
// int 1 -1 2
// 栈低 table -2 1
lua_gettable(L, -2);//获取table中的第一个元素value 并把这个value放到栈顶
//------------------------此时栈中的内容应该如下-------------------
// 说明 栈内容 排序 排序
// int 1007 -1 2
// 栈低 table -2 1
if (lua_isnumber(L, 2)){ //再获取栈顶的1007 value
int luanumber = lua_tonumber(L, 2);
CCLOG("luanumber = %d", luanumber);
}
//然后出栈 这一步很重要,同样地我们也应该在上面多参数传递时,获取完栈顶数值之后,出栈,
//让C语言保持多栈顶的控制,而不改变整个栈
//把栈顶的数值弹出
lua_pop(L, 1);
//------------------------此时栈中的内容应该如下-------------------
// 说明 栈内容 排序 排序
// 栈低 table -1 1
//得到这个原始干净的栈之后 就会继续获取下面的值
lua_pushnumber(L, 2);
lua_gettable(L, -2);
if (lua_isstring(L, -1)){
std::string luastring = lua_tostring(L, -1);
const char* numberA = luastring.c_str();
CCLOG("numberA = %s", numberA);
}
lua_pop(L, 1);
//同理可以得到
lua_pushnumber(L, 3);
lua_gettable(L, -2);
if (lua_isstring(L, -1)){
std::string luastring = lua_tostring(L, -1);
const char* numberB = luastring.c_str();
CCLOG("numberA = %s", numberB);
}
CCLOG("---->roleid = %s", lualog);
<pre name="code" class="java"> CCLOG("---->roleid = %s", lualog);
CCLOG("---->money = %d", money);
CCLOG("---->productName = %s", productName);
CCLOG("---->callBackStr = %s", callBackStr);
CCLOG("---->gameGold = %s", gameGold);
CCLOG("---->rate = %d", rate);
在最后的log输出,你会发现,所有的字符串的输出都是错乱的。
这是为什么呢??没有办法,我只好进行调试了,VS2013的F5按一下。
一步by一步运行下去,然后你会发现。
首先,我们先看roleid这个字段。
注意看黄色的标志箭头。(按行来进行调试)
运行完luastring.c_str之后,lualog的内存地址上的值为1008。
接着,
跳出if之后,什么鬼?lualog的值被改变了?变为空字符串了? 怎么可能?
我就想,是不是luastring的值改变,导致指针指向的值也不存在了。
接着我调试一次,把所有有关的内存地址和指针都捕捉一下。
然后,惊人地发现:
其实luastring的值其实没有变的,变的是字符串指针指向。既然,本来传递的值没有改变,那么如何把这个值取下来,运用到后面的方法中去呢?
这个时候,就需要查看源码了,我相信,lua与C的交互中一定存在同样的需求,传递字符串,那么他们api中是如何取得字符串的值呢?
我翻看了C api中的这个文件:lua_cocos2dx_network_manual.cpp
里面有这样的方法:
看到没有,他们是使用tolua_tostring来取值字符串的值的,取值之后,把值运用到其他C方法中。
看到这里就可以了,把上面方法中所有通过lua_tostring方法获取字符串的函数改为tolua_tostring。
完美解决。