私はプロジェクトでcinvoke-luaを使いたいですが、私のターゲット環境はLua 5.2しか利用できません。残念ながら、ライブラリは5.1用に書かれており、直接下位互換性はありません。cinvoke-luaをLuaに移植する5.2
私は既にlua_objlen
をlua_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を使用することですが、私の場合は直接上にストリングを押しません。
https://stackoverflow.com/questions/10087226/lua-5-2-lua-globalsindex-alternative – lhf