From C, finding a Lua function by its name

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

From C, finding a Lua function by its name

Laurent FAILLIE
Hello,

I'm looking for a way to find out a function from it's name.

I understood from the documentation that function are handled as "normal" object, so with my test code, I'm expecting to find it in global variable table.
So I'm calling lua_getglobal() on the function name but it fails and returns a NIL.

I did this little test code .

--- Test.lua ---
function UPSBatCharge( topic, val )
    print(topic, val);
end
---

---- FindFunc.c ---
#include <stdio.h>
#include <stdlib.h>

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

lua_State *L;

void clean_lua(void){
    lua_close(L);
}

int findUserFunc( const char *fn ){
    lua_getglobal(L, fn);
    if( lua_type(L, -1) != LUA_TFUNCTION ){
        fprintf(stderr, "*E* \"%s\" is not a function, a %s.\n", fn, lua_typename(L, lua_type(L, -1)) );
        lua_pop(L, 1);
        return LUA_REFNIL;
    }
    /* tbd */
    return LUA_REFNIL;
}

void main( void ){
    L = lua_open();
    luaL_openlibs(L);
    atexit(clean_lua);

    int err;
    if(( err = luaL_loadfile(L, "Test.lua") )){
        fprintf(stderr, "*F*  %s\n", lua_tostring(L, -1));
        exit(EXIT_FAILURE);
    }

    puts("File loaded");

    findUserFunc("UPSBatCharge");
   
    exit(EXIT_SUCCESS);
}
---

My need : I created a tool named Marcel (https://github.com/destroyedlolo/Marcel) which is, among other things, call Lua function when it receive some MQTT data. Those functions aim to take decision to raise an alert for example.
And the user has only to provide in the configuration file the name of the function to be called.

Thanks for your help.

Laurent

---

The misspelling master is on the Web.
  _________ 100 % Dictionnary Free !
/                    /(
/ Dico          / / Pleins d'autres fautes sur
/________ / /
(########( / http://destroyedlolo.info
Quoi, des fautes d'orthographe! Pas possible ;-D.
Reply | Threaded
Open this post in threaded view
|

Re: From C, finding a Lua function by its name

Rob Kendrick-2
On Tue, Jul 28, 2015 at 09:44:46AM +0000, Laurent FAILLIE wrote:
> Hello,
> I'm looking for a way to find out a function from it's name.
> I understood from the documentation that function are handled as "normal" object, so with my test code, I'm expecting to find it in global variable table.So I'm calling lua_getglobal() on the function name but it fails and returns a NIL.

Functions, much like other values such as 42, "spatula" and false do not
have names, they are values.

A function may have any number of variables that have names assoicated
with it; including zero.

The best you can hope for is to spider the entire environment looking
for a variable that contains the same function you're looking for and
also hope that it's a usefully named one.

B.

Reply | Threaded
Open this post in threaded view
|

Re: From C, finding a Lua function by its name

Dirk Laurie-2
2015-07-28 11:47 GMT+02:00 Rob Kendrick <[hidden email]>:

> On Tue, Jul 28, 2015 at 09:44:46AM +0000, Laurent FAILLIE wrote:
>> Hello,
>> I'm looking for a way to find out a function from it's name.
>> I understood from the documentation that function are handled as "normal" object, so with my test code, I'm expecting to find it in global variable table.So I'm calling lua_getglobal() on the function name but it fails and returns a NIL.
>
> Functions, much like other values such as 42, "spatula" and false do not
> have names, they are values.
>
> A function may have any number of variables that have names assoicated
> with it; including zero.
>
> The best you can hope for is to spider the entire environment looking
> for a variable that contains the same function you're looking for and
> also hope that it's a usefully named one.

If the function name is not found by lua_getglobal it may be a local
function or an upvalue. You can query those names via lua_getlocal and
lua_getupvalue, but you'll have to loop through the possibilities;
there
is no name-based access.

Reply | Threaded
Open this post in threaded view
|

Re: From C, finding a Lua function by its name

Michael Welsh Duggan
In reply to this post by Laurent FAILLIE
Laurent FAILLIE <[hidden email]> writes:

> Hello,
> I'm looking for a way to find out a function from it's name.
> I understood from the documentation that function are handled as
> "normal" object, so with my test code, I'm expecting to find it in
> global variable table.So I'm calling lua_getglobal() on the function
> name but it fails and returns a NIL.
>
> I did this little test code .
> --- Test.lua ---function UPSBatCharge( topic, val )
>     print(topic, val);
> end
> ---
> ---- FindFunc.c ---#include <stdio.h>

[...]

> void main( void ){
>     L = lua_open();
>     luaL_openlibs(L);
>     atexit(clean_lua);
>
>     int err;
>     if(( err = luaL_loadfile(L, "Test.lua") )){
>         fprintf(stderr, "*F*  %s\n", lua_tostring(L, -1));
>         exit(EXIT_FAILURE);
>     }
>
>     puts("File loaded");
>
>     findUserFunc("UPSBatCharge");
>    
>     exit(EXIT_SUCCESS);
> }---

luaL_loadfile loads the file and returns the contents (a chunk) as an
executable function on the stack.  It doesn't actually execute the file.
After the loadfile call, you need to execute it before it will create
the UPSBatCharge function in the globals table.  You probably want to
add something like:

  if ((err = lua_pcall(L, 0, 0, 0)) != LUA_OK) {
    ...
  }

afterward.

--
Michael Welsh Duggan
([hidden email])

Reply | Threaded
Open this post in threaded view
|

Re: From C, finding a Lua function by its name

Laurent FAILLIE
Ha, ok, thanks Michael.

I changed my code like that
---
    ...
    int err = luaL_loadfile(L, "Test.lua") || lua_pcall(L, 0, 0, 0);
    if(err){
        fprintf(stderr, "*F*  %s\n", lua_tostring(L, -1));
        exit(EXIT_FAILURE);
    }
    ...
---
and now it's working.

Thanks a lot.

Laurent

 ---
The misspelling master is on the Web.
  _________ 100 % Dictionnary Free !
/                    /(
/ Dico          / / Pleins d'autres fautes sur
/________ / /
(########( / http://destroyedlolo.info
Quoi, des fautes d'orthographe! Pas possible ;-D.





Le Mardi 28 juillet 2015 14h25, Michael Welsh Duggan <[hidden email]> a écrit :


Laurent FAILLIE <[hidden email]> writes:


> Hello,
> I'm looking for a way to find out a function from it's name.
> I understood from the documentation that function are handled as
> "normal" object, so with my test code, I'm expecting to find it in
> global variable table.So I'm calling lua_getglobal() on the function
> name but it fails and returns a NIL.
>
> I did this little test code .
> --- Test.lua ---function UPSBatCharge( topic, val )
>     print(topic, val);
> end
> ---
> ---- FindFunc.c ---#include <stdio.h>

[...]

> void main( void ){
>     L = lua_open();
>     luaL_openlibs(L);
>     atexit(clean_lua);
>
>     int err;
>     if(( err = luaL_loadfile(L, "Test.lua") )){
>         fprintf(stderr, "*F*  %s\n", lua_tostring(L, -1));
>         exit(EXIT_FAILURE);
>     }
>
>     puts("File loaded");
>
>     findUserFunc("UPSBatCharge");
>    
>     exit(EXIT_SUCCESS);

> }---

luaL_loadfile loads the file and returns the contents (a chunk) as an
executable function on the stack.  It doesn't actually execute the file.
After the loadfile call, you need to execute it before it will create
the UPSBatCharge function in the globals table.  You probably want to
add something like:

  if ((err = lua_pcall(L, 0, 0, 0)) != LUA_OK) {
    ...
  }

afterward.

--
Michael Welsh Duggan
([hidden email]
)