2017-12-21 17 views
1

私はプロジェクトでcinvoke-luaを使いたいですが、私のターゲット環境はLua 5.2しか利用できません。残念ながら、ライブラリは5.1用に書かれており、直接下位互換性はありません。cinvoke-luaをLuaに移植する5.2

私は既にlua_objlenlua_rawlenに変更しました(これは正しい置き換えと思われる)。

他のものはLUA_GLOBALSINDEXの使用の束であり、これはもはや5.2には存在しません。

struct CBStruct { 
    CInvCallback *cb; 
    CInvFunction *func; 
    CInvContext *ctx; 
    lua_Integer key; 
    lua_State *l; 
}; 

int _ccallback_gc(lua_State *l) { 
    struct CBStruct *cb = touserdata(l, 1); 

    lua_pushinteger(l, cb->key); 
    lua_pushnil(l); 
    lua_settable(l, LUA_GLOBALSINDEX); 

    if (cb->cb) { 
     cinv_callback_delete(cb->ctx, cb->cb); 
     cb->cb = NULL; 
    } 
    if (cb->func) { 
     cinv_function_delete(cb->ctx, cb->func); 
     cb->func = NULL; 
    } 

    return 0; 
} 

void _ccallback_invoked(CInvFunction *f, void *parameters[], 
    void *returnout, void *userdata) { 
    struct CBStruct *cb = userdata; 
    int usertable, pindex, index, retindex; 
    int numargs, i; 

    lua_pushinteger(cb->l, cb->key); 
    lua_gettable(cb->l, LUA_GLOBALSINDEX); 
    usertable = lua_gettop(cb->l); 

    if (lua_isnil(cb->l, usertable)) { 
     lua_pushstring(cb->l, 
      "C callback being called for an object which has been collected"); 
     lua_error(cb->l); 
    } 
    lua_getfield(cb->l, usertable, "cbfunc"); 

    lua_getfield(cb->l, usertable, "params"); 
    pindex = lua_gettop(cb->l); 
    numargs = (int)lua_rawlen(cb->l, pindex); 

    for (i = 0; i < numargs; i++) { 
     lua_pushinteger(cb->l, i + 1); 
     lua_gettable(cb->l, pindex); 
     index = lua_gettop(cb->l); 

     unmarshal_retval(cb->l, index, parameters[i]); 

     lua_remove(cb->l, index); 
    } 
    lua_remove(cb->l, pindex); 

    lua_call(cb->l, numargs, 1); 
    retindex = lua_gettop(cb->l); 

    lua_getfield(cb->l, usertable, "return"); 
    index = lua_gettop(cb->l); 
    if (!isvoid(cb->l, index)) { 
     marshal_basic(cb->l, returnout, index, retindex); 
    } 
    lua_remove(cb->l, index); 

    lua_pop(cb->l, 2); // return value and usertable 
} 

int _clibrary_new_callback(lua_State *l) { 
    struct CBStruct *cbs; 
    struct LibStruct *lib; 
    CInvFunction *func; 
    CInvCallback *cb; 
    int i; 
    void *ep; 
    int retval; 
    int numargs = lua_gettop(l); 
    if (numargs < 3) { 
     lua_pushstring(l, "usage: clibrary:new_callback(rettype, cbfunc, ...)"); 
     lua_error(l); 
    } 

    lua_getfield(l, 1, "ud"); 
    lib = touserdata(l, -1); 
    lua_pop(l, 1); 

    func = parsefunction(l, lib->ctx, 2, 1, lib->cc); 

    lua_newtable(l); 
    retval = lua_gettop(l); 

    cbs = lua_newuserdata(l, sizeof(struct CBStruct)); 
    cbs->func = func; 
    cbs->ctx = lib->ctx; 
    cbs->l = l; 

    cb = cinv_callback_create(lib->ctx, func, cbs, _ccallback_invoked); 
    if (!cb) { 
     lua_pushstring(l, cinv_context_geterrormsg(lib->ctx)); 
     cinv_function_delete(lib->ctx, func); 
     lua_error(l); 
    } 
    cbs->cb = cb; 
    cbs->key = time(NULL); 

    while (1) { 
     lua_pushinteger(l, cbs->key); 
     lua_gettable(l, LUA_GLOBALSINDEX); 
     if (!lua_isnil(l, -1)) { 
      lua_pop(l, 1); 
      cbs->key++; 
      continue; 
     } 
     lua_pop(l, 1); 
     lua_pushinteger(l, cbs->key); 
     lua_pushvalue(l, retval); 
     lua_settable(l, LUA_GLOBALSINDEX); 
     break; 
    } 

    lua_newtable(l); 
    lua_pushcfunction(l, _ccallback_gc); 
    lua_setfield(l, -2, "__gc"); 
    lua_setmetatable(l, -2); 
    lua_setfield(l, -2, "ud"); 

    ep = cinv_callback_getentrypoint(lib->ctx, cb); 
    if (!ep) { 
     lua_pushstring(l, cinv_context_geterrormsg(lib->ctx)); 
     lua_error(l); 
    } 
    lua_pushlightuserdata(l, ep); 
    lua_setfield(l, -2, "ep"); 

    lua_pushvalue(l, 2); 
    lua_setfield(l, -2, "return"); 

    lua_newtable(l); 
    for (i = 4; i <= numargs; i++) { 
     lua_pushinteger(l, i - 3); 
     lua_pushvalue(l, i); 
     if (isvoid(l, lua_gettop(l))) 
      lua_pop(l, 2); 
     else 
      lua_settable(l, -3); 
    } 
    lua_setfield(l, -2, "params"); 

    lua_pushvalue(l, 3); 
    lua_setfield(l, -2, "cbfunc"); 

    lua_pushvalue(l, 1); 
    lua_setfield(l, -2, "lib"); 

    return 1; 
} 

私はLuaの内部の仕組みを持つ、文字通り経験がないので、誰かがどれだけこれらを置き換えるために私に言うことができるならば、それははるかに高く評価されたい:3つの機能で4回参照されます。スタックオーバーフローについては、ここではたくさんの記事がありますが、それは別のコンテキストで使用されているように見えますが、ソリューションは主にlua_setglobalを使用することですが、私の場合は直接上にストリングを押しません。

+0

https://stackoverflow.com/questions/10087226/lua-5-2-lua-globalsindex-alternative – lhf

答えて

0

lua_push*(KEY); 
    lua_push*(VALUE); 
    lua_settable(l, LUA_GLOBALSINDEX); 

lua_pushglobaltable(l); 
    lua_push*(KEY); 
    lua_push*(VALUE); 
    lua_settable(l, -3); 
    lua_pop(l,1); 

lua_push*(KEY); 
    lua_gettable(l, LUA_GLOBALSINDEX); 

に置き換え

lua_pushglobaltable(l); 
    lua_push*(KEY); 
    lua_settable(l, -2); 
    lua_pop(l,1); 

これは、コードが何をしているのかわかるようにすれば、おそらく単純化することができます。

+0

ありがとうございます、私はあなたが "可能な重複"としてリンクした回答よりはるかに明確であることがわかりました。今コンパイルすると、実際に動作するかどうかは後でテストすることしかできません。 – Starchild

関連する問題