我想包装C计时器(不是警报)并在lua中使用它,就像我一样 可以指定在一秒钟过后触发的回调函数。 为了使用多个计时器,计时器ID和回调将存储到表中, 但是当调用'lua_rawset'时发生了分段错误,所以我使用了stack_dump 检查lua堆栈,第66行'lua_rawget'返回nil(lr_register_timer, 以FIXME标记),这里有什么问题?对不起,我的英语很差。 欢呼声。
lua代码:
local lt = luatimer
lt.register_timer(1, function(id)
io.stdout:write("id" .. id .. "timeout\n");
end)
C代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
#include "timer.h"
static lua_State *L;
static void stack_dump(lua_State *L, FILE *fp)
{
int i;
int top = lua_gettop(L);
for (i = 1; i <= top; i++) {
int t = lua_type(L, i);
switch (t) {
case LUA_TSTRING: fprintf(fp, "'%s'", lua_tostring(L, i)); break;
case LUA_TBOOLEAN: fprintf(fp, lua_toboolean(L, i) ? "true" : "false"); break;
case LUA_TNUMBER: fprintf(fp, "%g", lua_tonumber(L, i)); break;
default: fprintf(fp, "%s", lua_typename(L, t)); break;
}
fprintf(fp, " ");
}
fprintf(fp, "\n");
}
struct timer_env {
int id;
struct event *ev;
};
static void callback_timer_wrap(int id, void *arg)
{
struct timer_env *env = arg;
/* get timer id table */
lua_pushlightuserdata(L, &L);
lua_rawget(L, LUA_REGISTRYINDEX);
lua_pushinteger(L, env->id);
lua_gettable(L, -2);
/* call lua handler with one result */
lua_pushinteger(L, env->id);
if (lua_pcall(L, 1, 1, 0) == 0) {
lua_pop(L, 1); /* pop result */
}
}
/* id, callback */
static int lr_register_timer(lua_State *L)
{
struct timer_env *env;
int id;
int err;
id = (int)luaL_checkinteger(L, 1);
if (!lua_isfunction(L, 2) || lua_iscfunction(L, 2))
return 0;
/* set lua handler */
lua_pushlightuserdata(L, &L);
lua_rawget(L, LUA_REGISTRYINDEX); /* FIXME */
lua_pushvalue(L, 1); /* key: id */
lua_pushvalue(L, 2); /* value: callback */
stack_dump(L, stderr);
/* FIXME crashed */
lua_rawset(L, -3);
lua_pop(L, 1);
env = malloc(sizeof(*env));
memset(env, 0, sizeof(*env));
env->id = id;
if ((err = register_timer(id, callback_timer_wrap, env)) < 0)
free(env);
lua_pushinteger(L, err);
return 1;
}
static const luaL_Reg luatimer_lib[] = {
{ "register_timer", lr_register_timer },
{ NULL, NULL }
};
static int luaopen_luatimer(lua_State *L)
{
luaL_register(L, "luatimer", luatimer_lib);
/* timer id table */
lua_pushlightuserdata(L, &L); /* key */
lua_newtable(L); /* value */
lua_rawset(L, LUA_REGISTRYINDEX);
return 1;
}
int luaenv_init(void)
{
L = luaL_newstate();
luaL_openlibs(L);
lua_pushcfunction(L, luaopen_luatimer);
lua_pushstring(L, "luatimer");
lua_call(L, 1, 0);
return 0;
}
void luaenv_exit(void)
{
if (L)
lua_close(L);
}
答案 0 :(得分:0)
非常感谢,我犯了一个愚蠢的错误,我在本地变量和全局变量中使用相同的名称L
。对不起
感谢greatwold和immibis