2013-05-20 9 views
8

के पीछे क्या अंतर है मैं lua का उपयोग कर रहा हूं और मुझे पता है कि पीसीएल सुरक्षित कॉलिंग के लिए है और मेरा सवाल यह है कि अगर कॉल करने के दोनों तरीके एक ही सी कोड पर आते हैं। जैसेसामान्य फ़ंक्शन कॉल और पीसी

function a(arg) 
    ... 
end 

सामान्य बुला:

a(arg) 

संरक्षित कॉल:

pcall(a, arg) 

असल में मैं भ्रष्ट से lua_State की रक्षा के लिए 'lua_lock/lua_unlock' का उपयोग कर रहा हूँ। और स्रोत बनाएं (lua 5.1.4) मैं देख सकता हूं कि 'lua_pcall' 'lua_lock/lua_unlock' कह रहा है, लेकिन मुझे यकीन नहीं है कि फ़ंक्शन कॉल का सामान्य तरीका 'lua_pcall' पर आधारित है या 'lua_lock/lua_unlock' का उपयोग कर रहा है? यदि नहीं, तो क्या इसका मतलब यह है कि 'lua_lock/lua_unlock' से लाभ प्राप्त करने के लिए मुझे सभी फ़ंक्शन कॉलिंग को 'pcall (...)' में बदलना होगा?

क्या कोई समझा सकता है? धन्यवाद

उत्तर

15

pcall लुआ में त्रुटियों को संभालने के लिए उपयोग किया जाता है।

पहले हम एक समारोह जो मुझे पता निम्नलिखित हमारी पहली उदाहरण हम परिभाषित के रूप में अब एक त्रुटि

function makeError(n) 
    return 'N'+n; 
end 

का उत्पादन करेगा बनाने: मैं निम्नलिखित उदाहरण यह कैसे उपयोग करने के लिए प्रदर्शन करने के लिए बनाया है

function pcallExample1() 
    if pcall(makeError,n) then 
     print("no error!") 
    else 
     print("That method is broken, fix it!") 
    end 
end 

हम आह्वान pcallExample1

प्रदर्शन करने के लिए

function pcallExample2() 
    if makeError(5) then 
     print("no error!") 
    else 
     print("That method is broken, fix it!") 
    end 
end 

इस लागू त्रुटि होगा unhanded रहते हैं और बुलबुला:

Lua 5.1.3 Copyright (C) 1994-2008 Lua.org, PUC-Rio 
That method is broken, fix it! 

विपरीत प्रदर्शित करने के लिए: 210

और आउटपुट प्राप्त

lua: /Users/henryhollinworth/Desktop/s.lua:2: attempt to perform arithmetic on a string value 

के संदर्भ में, 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)); 
} 

रूप 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; 
} 

इसके विपरीत 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); 
} 

को ध्यान दें कि दोनों lua_lock() और lua_unlock() का इस्तेमाल करते हैं परिभाषित किया गया है। lua_State दोनों लॉक और अनलॉक करें।

+0

ध्यान दें कि आमतौर पर - विशेष रूप से विकास के लिए - 'xpcall' का उपयोग करना बेहतर होता है क्योंकि आप वास्तव में एक त्रुटि संदेश प्राप्त कर सकते हैं और इसके बाहर ट्रेसबैक प्राप्त कर सकते हैं, जबकि यह त्रुटि के मामले में लुआ रनटाइम को प्रभावित नहीं करता है। – dualed

संबंधित मुद्दे