2010-11-18 3 views
1

Обычно можно было бы нажать «userdata», когда данные не являются стандартными типами Lua (число, строка, bool и т. Д.).Нажатие указателя исполняемой функции?

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

EDIT: Чтобы добавить определенную ясность, значение должно быть возвращено функцией, переданной Lua через API C.

ответ

1

Вы можете вернуть UserData с метатаблицы, что прокси вашу функцию C через __call Метаметод. Таким образом, 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. Вышеупомянутый код отвечает на ваш вопрос буквально, но это, вероятно, слишком велико для того, что вам действительно нужно выполнить.

+1

WAAAY более спроектирован. –

+0

@caspin Следовательно, редактирование в конце и мой комментарий к ответу Дуга. Чтобы положить это в исторический контекст, он изначально отказался от ответа Дага и снова подумал о проблеме. –

9

Использование 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; 
} 
+0

Downvote, потому что 'lua_pushcfunction' подталкивает' lua_CFunction' - который, очевидно, может быть только типа 'lua_CFunction'. – 2010-11-18 05:20:21

+4

Это верно, но функция типа lua_CFunction может быть создана, чтобы вытащить параметры из стека Lua и передать их целевой функции C. Это называется созданием привязок! –

+0

Теперь я вижу. Ну, рассмотрите этот ответ так же, как принято, к сожалению, я могу только официально принять его. – 2010-11-19 04:46:35

Смежные вопросы