Нажав указатель на исполняемую функцию? - PullRequest
2 голосов
/ 18 ноября 2010

Обычно можно выдвигать 'userdata' только тогда, когда данные не относятся ни к одному из стандартных типов Lua (число, строка, bool и т. Д.).

Но как бы вы фактически передали указатель 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?Если да, то как (Примеры были бы оценены)?

РЕДАКТИРОВАТЬ: Чтобы добавить некоторую ясность, предполагается, что значение должно быть возвращено функцией, доступной Lua через C API.

Ответы [ 2 ]

10 голосов
/ 18 ноября 2010

Использование 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 голос
/ 18 ноября 2010

Вы можете вернуть пользовательские данные с метатаблицей, которая проксирует вашу функцию C через метаметод __call.Таким образом, пользовательские данные могут быть вызваны как функция.Ниже приведен полный пример программы.

#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.Код выше отвечает на ваш вопрос буквально, но это, вероятно, излишне для того, что вам действительно нужно сделать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...