推送可执行函数指针?

时间:2010-11-18 00:44:19

标签: lua

当数据不是Lua的标准类型(数字,字符串,bool等)时,通常只会推送'userdata'。

但是你如何将实际的Function指针推送到Lua(而不是userdata;因为userdata在Lua中不能作为函数执行),假设函数看起来像这样:

void nothing(const char* stuff)
{
    do_magic_things_with(stuff);
}

返回的值应该与此本机Lua函数的返回值相似:

function things()
    return function(stuff)
        do_magic_things_with(stuff)
    end
end

这可能与C API有关吗?如果是,如何(例子将被赞赏)?

编辑:为了增加一些清晰度,该值应该由通过C API向Lua公开的函数返回。

2 个答案:

答案 0 :(得分:10)

使用lua_pushcfunction

示例包含在PiL

这是一个遵循当前接受的答案形式的示例。

#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
#include <stdio.h>

/* this is the C function you want to return */
static void
cfunction(const char *s)
{
    puts(s);
}

/* this is the proxy function that acts like cfunction */
static int
proxy(lua_State *L)
{
    cfunction(luaL_checkstring(L, 1));
    return 0;
}

/* this global function returns "cfunction" to Lua. */
static int
getproxy(lua_State *L)
{
    lua_pushcfunction(L, &proxy);
    return 1;
}

int
main(int argc, char **argv)
{
    lua_State *L;

    L = luaL_newstate();

    /* set the global function that returns the proxy */
    lua_pushcfunction(L, getproxy);
    lua_setglobal(L, "getproxy");

    /* see if it works */
    luaL_dostring(L, "p = getproxy() p('Hello, world!')");

    lua_close(L);

    return 0;
}

答案 1 :(得分:1)

您可以通过__call元方法返回带有代理您的C函数的元表的userdata。这样,userdata可以像函数一样被调用。以下是完整的程序示例。

#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
#include <stdio.h>

/* this is the C function you want to return */
static void
cfunction(const char *s)
{
    puts(s);
}

/* this is the proxy function that will be used as the __call metamethod */
static int
proxy(lua_State *L)
{
    luaL_checkudata(L, 1, "proxy");
    cfunction(luaL_checkstring(L, 2));
    return 0;
}

/* this global function returns the C function with a userdata proxy */
static int
getproxy(lua_State *L)
{
    lua_newuserdata(L, sizeof (int));
    luaL_getmetatable(L, "proxy");
    lua_setmetatable(L, -2);
    return 1;
}

int
main(int argc, char **argv)
{
    lua_State *L;

    L = luaL_newstate();

    /* create the proxy metatable */
    luaL_newmetatable(L, "proxy");
    lua_pushcfunction(L, proxy);
    lua_setfield(L, -2, "__call");

    /* set the global function that returns the proxy */
    lua_pushcfunction(L, getproxy);
    lua_setglobal(L, "getproxy");

    /* see if it works */
    luaL_dostring(L, "p = getproxy() p('Hello, world!')");

    lua_close(L);

    return 0;
}

回想起来,我完全没想到你在问什么。您真正需要做的就是创建一个类型为lua_CFunction的函数,该函数从Lua堆栈中提取参数并将它们传递给目标C函数。上面的代码从字面上回答了你的问题,但对你真正需要完成的事情来说可能有些过分。

相关问题