在lua_pcall之前设置不透明句柄时,我无法从C正确调用lua例程。 (注意:环境:Linux / OpenSuse42.2与LUA-5.3和GCC-5 )
我正在寻找的序列。
您可以在此处查看我的LUA代码。从LUA调用AFB_sucess时,我无法检索我的userdata。
似乎:
问题:当使用lua_pcall时,如何实现user_data,以便当LUA到达恰好在C中实现的回调时,我可以检索我的opaque句柄?
涉及的关键行是。
常规用于创建/检索不透明句柄
STATIC LuaAfbContextT *LuaCtxCheck (lua_State *luaState, int index) {
LuaAfbContextT *afbContext;
luaL_checktype(luaState, index, LUA_TUSERDATA);
afbContext = (LuaAfbContextT *)luaL_checkudata(luaState, index, CTX_TOKEN);
if (afbContext == NULL && afbContext->ctxMagic != CTX_MAGIC) {
luaL_error(luaState, "Fail to retrieve user data context=%s", CTX_TOKEN);
AFB_ERROR ("afbContextCheck error retrieving afbContext");
return NULL;
}
return afbContext;
}
STATIC LuaAfbContextT *LuaCtxPush (lua_State *luaState, afb_req request, const char* info) {
LuaAfbContextT *afbContext = (LuaAfbContextT *)lua_newuserdata(luaState, sizeof(LuaAfbContextT));
if (!afbContext) {
AFB_ERROR ("LuaCtxPush fail to allocate user data context");
return NULL;
}
luaL_setmetatable(luaState, CTX_TOKEN);
afbContext->ctxMagic=CTX_MAGIC;
afbContext->info=strdup(info);
afbContext->request= request;
return afbContext;
}
从C创建LUA例程
// Push AFB client context on the stack
LuaAfbContextT *afbContext= LuaCtxPush(luaState, request, func);
if (!afbContext) goto OnErrorExit;
// load function (should exist in CONTROL_PATH_LUA
lua_getglobal(luaState, func);
// push arguments on the stack
if (json_object_get_type(args) != json_type_array) {
count= LuaPushArgument (args);
} else {
for (int idx=0; idx<json_object_array_length(args); idx++) {
count += LuaPushArgument (json_object_array_get_idx(args, idx));
if (err) break;
}
}
从C
调用LUA的例程 static const luaL_Reg afbFunction[] = {
{"notice" , LuaPrintNotice},
{"warning", LuaPrintWarning},
{"service", LuaAfbService},
{"success", LuaAfbSuccess},
{"fail" , LuaAfbFail},
{NULL, NULL} /* sentinel */
};
// Create Binding Event at Init
PUBLIC int LuaLibInit () {
int err, index;
// search for default policy config file
json_object *luaScriptPathJ = ScanForConfig(CONTROL_PATH_LUA , "onload", "lua");
// open a new LUA interpretor
luaState = luaL_newstate();
if (!luaState) {
AFB_ERROR ("LUA_INIT: Fail to open lua interpretor");
goto OnErrorExit;
}
// load auxiliary libraries
luaL_openlibs(luaState);
// redirect print to AFB_NOTICE
luaL_newlib(luaState, afbFunction);
lua_setglobal(luaState, "AFB");
// Push AFB client context on the stack
LuaAfbContextT *afbContext= LuaCtxPush(luaState, request, func);
if (!afbContext) goto OnErrorExit;
// load function (should exist in CONTROL_PATH_LUA
lua_getglobal(luaState, func);
// push arguments on the stack
if (json_object_get_type(args) != json_type_array) {
count= LuaPushArgument (args);
} else {
for (int idx=0; idx<json_object_array_length(args); idx++) {
count += LuaPushArgument (json_object_array_get_idx(args, idx));
if (err) break;
}
}
我的LUA脚本
-- Adjust Volume function of vehicle speed
function Adjust_Volume_Speed (speed_meters_second)
AFB:notice("In Adjust_Volume_Speed")
print (string.format("***** Adjust_Volume_Speed speed=%d count=%d", speed_meters_second, count));
-- compute volume
volume = speed_meters_second * 2
count=count+1
AFB:success (1234, volume, count, 5678)
end