lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]

2009/10/17 Jiří Prymus <>:
> Thanks for answers.
> I'm little confused from yours replies but I try to explain my problem clearly.
> I need to pass lua function to C++ wrapper function where it will be
> used as "update event" of GtkTrackBar widget.
> My wrapper is compiled as shared library for lua.
> Maybe that sample code make this problem clear.
> C++ wrapper function -----------------
> static int luacv_cvCreateTrackbar(lua_State *L)
> {
>  const char *trackbar_name=luaL_checkstring(L,1);
>  const char *window_name=luaL_checkstring(L,2);
>  int value=luaL_checkint(L,3);
>  int count=luaL_checkint(L,4);
>  CvTrackbarCallback on_change=NULL;
>  if (lua_isfunction(L,5))
>    on_change=(CvTrackbarCallback)lua_tocfunction(L,5);
>  else
>    luaL_error(L,"luacv.cvCreateTrackbar(string trackbar_name,string
> window_name,int value,int count, void func(int pos))");
>  cvCreateTrackbar(trackbar_name,window_name,&value,count,on_change);
>  return 0;
> }
> Type CvTrackbarCallback is defined like
> typedef void (CV_CDECL *CvTrackbarCallback)(int pos);
> As you can see , the "on_change" variable  is pointer to c function
> with int as argument.
> Lua script may be look like this
> cv=require('luacv')
> function on_trackbar(pos)
> some stuff here..
> end
> cv.cvCreateTrackbar(tbarname,wndname,edge_thresh,100,on_trackbar)
> So I can get pointer of lua function "on_trackbar" via stack in
> wrapper , but when I want to convert it to c function, it doesn't
> work.

You cannot get a pointer to a Lua function from C and call it directly
as if it were a C function. There is no way to convert it. Instead,
you must always get the Lua function onto the stack (from somewhere
already inside the Lua "universe"), and call it using

The trick is finding the right place to store it. Ideally you don't
want to be doing any more than a single table lookup to get your

For example, you could decide that the place to look for your function
is a global variable with a specific name:

  lua_getglobal(L, "on_trackbar");
  if (lua_isfunction(L,-1)) {

Or, you could use the luaL_ref()/luaL_unref() system (look them up in
the Reference Manual if you have not used them before) to get an
integer reference to your function:

  // Lua function on_trackbar() is on top of the stack
  int on_trackbar_id = luaL_ref(L, LUA_REGISTRYINDEX);
  // on_trackbar() has been removed from the stack,
  //  and stored in the registry table. on_trackbar_id now stores
  //  a unique identifier for it.

  // ... later on, when we want to call on_trackbar():
  luaL_unref(L, LUA_REGISTRYINDEX, on_trackbar_id);
  // on_trackbar() is back on top of the stack again, so we can call it:

There are other options as well, but it's all basically variations on
the same thing.