我正在使用lua,我知道pcall是用于受保护的调用,我的问题是,如果两种方式都调用同一个C代码.例如
function a(arg)
...
end
Run Code Online (Sandbox Code Playgroud)
正常通话:
a(arg)
Run Code Online (Sandbox Code Playgroud)
保护电话:
pcall(a, arg)
Run Code Online (Sandbox Code Playgroud)
实际上我使用'lua_lock/lua_unlock'来保护lua_State免受腐败.并形成源(lua 5.1.4)我可以看到'lua_pcall'正在调用'lua_lock/lua_unlock',但我不确定函数调用的正常方式是否也基于'lua_pcall'或使用'lua_lock/lua_unlock'?如果没有,这是否意味着我必须将所有调用'pcall(...)'的函数更改为从'lua_lock/lua_unlock'中获益?
有人能解释一下吗 谢谢
Hen*_*nyH 17
pcall用于处理lua中的错误.我做了以下示例来演示如何使用它:
首先,我们创建一个我知道会产生错误的函数
function makeError(n)
return 'N'+n;
end
Run Code Online (Sandbox Code Playgroud)
现在作为我们的第一个例子,我们定义了以
function pcallExample1()
if pcall(makeError,n) then
print("no error!")
else
print("That method is broken, fix it!")
end
end
Run Code Online (Sandbox Code Playgroud)
我们援引 pcallExample1
pcallExample1()
Run Code Online (Sandbox Code Playgroud)
得到输出:
Lua 5.1.3 Copyright (C) 1994-2008 Lua.org, PUC-Rio
That method is broken, fix it!
Run Code Online (Sandbox Code Playgroud)
为了证明相反:
function pcallExample2()
if makeError(5) then
print("no error!")
else
print("That method is broken, fix it!")
end
end
Run Code Online (Sandbox Code Playgroud)
调用此方法将使错误保持不变并冒泡到显示:
lua: /Users/henryhollinworth/Desktop/s.lua:2: attempt to perform arithmetic on a string value
Run Code Online (Sandbox Code Playgroud)
就Cpcall 而言,pcall定义为
static int luaB_pcall (lua_State *L) {
int status;
luaL_checkany(L, 1);
lua_pushnil(L);
lua_insert(L, 1); /* create space for status result */
status = lua_pcallk(L, lua_gettop(L) - 2, LUA_MULTRET, 0, 0, pcallcont);
return finishpcall(L, (status == LUA_OK));
}
Run Code Online (Sandbox Code Playgroud)
哪里lua_pcallk是
LUA_API int lua_pcallk (lua_State *L, int nargs, int nresults, int errfunc,
int ctx, lua_CFunction k) {
struct CallS c;
int status;
ptrdiff_t func;
lua_lock(L);
api_check(L, k == NULL || !isLua(L->ci),
"cannot use continuations inside hooks");
api_checknelems(L, nargs+1);
api_check(L, L->status == LUA_OK, "cannot do calls on non-normal thread");
checkresults(L, nargs, nresults);
if (errfunc == 0)
func = 0;
else {
StkId o = index2addr(L, errfunc);
api_checkvalidindex(L, o);
func = savestack(L, o);
}
c.func = L->top - (nargs+1); /* function to be called */
if (k == NULL || L->nny > 0) { /* no continuation or no yieldable? */
c.nresults = nresults; /* do a 'conventional' protected call */
status = luaD_pcall(L, f_call, &c, savestack(L, c.func), func);
}
else { /* prepare continuation (call is already protected by 'resume') */
CallInfo *ci = L->ci;
ci->u.c.k = k; /* save continuation */
ci->u.c.ctx = ctx; /* save context */
/* save information for error recovery */
ci->u.c.extra = savestack(L, c.func);
ci->u.c.old_allowhook = L->allowhook;
ci->u.c.old_errfunc = L->errfunc;
L->errfunc = func;
/* mark that function may do error recovery */
ci->callstatus |= CIST_YPCALL;
luaD_call(L, c.func, nresults, 1); /* do the call */
ci->callstatus &= ~CIST_YPCALL;
L->errfunc = ci->u.c.old_errfunc;
status = LUA_OK; /* if it is here, there were no errors */
}
adjustresults(L, nresults);
lua_unlock(L);
return status;
}
Run Code Online (Sandbox Code Playgroud)
与之相反 lua_callk
LUA_API void lua_callk (lua_State *L, int nargs, int nresults, int ctx,
lua_CFunction k) {
StkId func;
lua_lock(L);
api_check(L, k == NULL || !isLua(L->ci),
"cannot use continuations inside hooks");
api_checknelems(L, nargs+1);
api_check(L, L->status == LUA_OK, "cannot do calls on non-normal thread");
checkresults(L, nargs, nresults);
func = L->top - (nargs+1);
if (k != NULL && L->nny == 0) { /* need to prepare continuation? */
L->ci->u.c.k = k; /* save continuation */
L->ci->u.c.ctx = ctx; /* save context */
luaD_call(L, func, nresults, 1); /* do the call */
}
else /* no continuation or no yieldable */
luaD_call(L, func, nresults, 0); /* just do the call */
adjustresults(L, nresults);
lua_unlock(L);
}
Run Code Online (Sandbox Code Playgroud)
请注意,两者都使用lua_lock()和lua_unlock().锁定和解锁lua_State.
| 归档时间: |
|
| 查看次数: |
8803 次 |
| 最近记录: |