Conversion Lua function to C function

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

Conversion Lua function to C function

Jiří Prymus
Hi,

I would like to know if there is any chance to convert lua function to
c function. I program a small opencv wrapper and there is one wrapping
function where I need pointer to function. And that's a problem
because I can get only pointer to Lua function and when I convert it
to C function then it does nothing. I know that lua functions are
stored in tables and that's probably why it  doesn't work.

In fact my problem is function gtk_signal_connect(...) where slot
function is my lua function.

Thanks for answer.

With regards,
Jiri Prymus
Reply | Threaded
Open this post in threaded view
|

Re: Conversion Lua function to C function

Wesley Smith
I don't completely follow, but you can store arbitrary function  
pointers as lightuserdata.

wes

On Oct 17, 2009, at 1:47 AM, Jiří Prymus <[hidden email]>  
wrote:

> Hi,
>
> I would like to know if there is any chance to convert lua function to
> c function. I program a small opencv wrapper and there is one wrapping
> function where I need pointer to function. And that's a problem
> because I can get only pointer to Lua function and when I convert it
> to C function then it does nothing. I know that lua functions are
> stored in tables and that's probably why it  doesn't work.
>
> In fact my problem is function gtk_signal_connect(...) where slot
> function is my lua function.
>
> Thanks for answer.
>
> With regards,
> Jiri Prymus
Reply | Threaded
Open this post in threaded view
|

Re: Conversion Lua function to C function

Asko Kauppi
What he needs to do is store the Lua function entry as such (make a  
copy, forget about C pointers) in the Lua registry or a userdata's  
environment. This is a common need and many source codes will carry  
samples. Then have a C side common callback which picks up that stored  
ref to the Lua function and executes it. I've made a helper for all  
this but that code is not public.

- asko

On 17.10.2009, at 21.03, Wesley Smith <[hidden email]> wrote:

> I don't completely follow, but you can store arbitrary function  
> pointers as lightuserdata.
>
> wes
>
> On Oct 17, 2009, at 1:47 AM, Jiří Prymus <[hidden email]> wro
> te:
>
>> Hi,
>>
>> I would like to know if there is any chance to convert lua function  
>> to
>> c function. I program a small opencv wrapper and there is one  
>> wrapping
>> function where I need pointer to function. And that's a problem
>> because I can get only pointer to Lua function and when I convert it
>> to C function then it does nothing. I know that lua functions are
>> stored in tables and that's probably why it  doesn't work.
>>
>> In fact my problem is function gtk_signal_connect(...) where slot
>> function is my lua function.
>>
>> Thanks for answer.
>>
>> With regards,
>> Jiri Prymus
Reply | Threaded
Open this post in threaded view
|

Re: Conversion Lua function to C function

Patrick Donnelly
In reply to this post by Jiří Prymus
On Sat, Oct 17, 2009 at 4:47 AM, Jiří Prymus <[hidden email]> wrote:

> Hi,
>
> I would like to know if there is any chance to convert lua function to
> c function. I program a small opencv wrapper and there is one wrapping
> function where I need pointer to function. And that's a problem
> because I can get only pointer to Lua function and when I convert it
> to C function then it does nothing. I know that lua functions are
> stored in tables and that's probably why it  doesn't work.
>
> In fact my problem is function gtk_signal_connect(...) where slot
> function is my lua function.

If you are manually calling the C function using its pointer, your
design is wrong. Learn how to use upvalues and hook functions.

--
-Patrick Donnelly

"Let all men know thee, but no man know thee thoroughly: Men freely
ford that see the shallows."

- Benjamin Franklin
Reply | Threaded
Open this post in threaded view
|

Re: Conversion Lua function to C function

Jiří Prymus
In reply to this post by Asko Kauppi
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)
    ...do 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.
No segmentation fault, but it does nothing.

I tried functions lua_tolightuserdata, lua_touserdata, lua_tocfunction
but none of them worked.


Thanks for answer and sorry for my english.

With regards,
Jiri Prymus

2009/10/17 Asko Kauppi <[hidden email]>:

> What he needs to do is store the Lua function entry as such (make a copy,
> forget about C pointers) in the Lua registry or a userdata's environment.
> This is a common need and many source codes will carry samples. Then have a
> C side common callback which picks up that stored ref to the Lua function
> and executes it. I've made a helper for all this but that code is not
> public.
>
> - asko
>
> On 17.10.2009, at 21.03, Wesley Smith <[hidden email]> wrote:
>
>> I don't completely follow, but you can store arbitrary function pointers
>> as lightuserdata.
>>
>> wes
>>
>> On Oct 17, 2009, at 1:47 AM, Jiří Prymus <[hidden email]> wrote:
>>
>>> Hi,
>>>
>>> I would like to know if there is any chance to convert lua function to
>>> c function. I program a small opencv wrapper and there is one wrapping
>>> function where I need pointer to function. And that's a problem
>>> because I can get only pointer to Lua function and when I convert it
>>> to C function then it does nothing. I know that lua functions are
>>> stored in tables and that's probably why it  doesn't work.
>>>
>>> In fact my problem is function gtk_signal_connect(...) where slot
>>> function is my lua function.
>>>
>>> Thanks for answer.
>>>
>>> With regards,
>>> Jiri Prymus
>
Reply | Threaded
Open this post in threaded view
|

Re: Conversion Lua function to C function

Duncan Cross
2009/10/17 Jiří Prymus <[hidden email]>:

> 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)
>    ...do 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
lua_call()/lua_pcall().

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
function.

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)) {
    lua_call(L,0,0);
  }

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:
  lua_call(L,0,0);

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

-Duncan
Reply | Threaded
Open this post in threaded view
|

Re: Conversion Lua function to C function

Wesley Smith
I've got a system that allows me to set Lua functions as callback
actions from GtkMenuItems.  You can find he code here:

// generic interface:
http://www.mat.ucsb.edu/projects/luaAV/browser/trunk/LuaAV/library/src/LuaAVMenu.cpp
471: int MenuItem :: action(lua_State *L)


// gtk callback system:
http://www.mat.ucsb.edu/projects/luaAV/browser/trunk/LuaAV/library/linux/LuaAVMenuLinux.cpp
93: void MenuBarImpl :: dispatch(MenuItem *mi)
419: void MenuItem :: implEnableAction()


wes
Reply | Threaded
Open this post in threaded view
|

Re: Conversion Lua function to C function

Luiz Henrique de Figueiredo
In reply to this post by Duncan Cross
> 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");

You can even use "strange" names such as "on trackbar" -- note the space.
In this way you avoid clashes with names in scripts.
Reply | Threaded
Open this post in threaded view
|

Re: Conversion Lua function to C function

GrayFace
In reply to this post by Jiří Prymus
The problem is in poorly designed callback. A good callback should at least
pass object pointer to callback function, or user data associated with it in
the best case. In that cases there wouldn't be any problems. This problem is
similar to passing a pointer to object method as callback. The only way I
see is to use a platform-dependant hack. For 32 bit Windows I can tell you
how to do it. It should be easy to tweak it to use it on 32 bit Linux.








----- Original Message -----
From: Jiří Prymus
To: Lua list
Sent: Saturday, October 17, 2009 11:22 PM
Subject: Re: Conversion Lua function to C function


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)
    ...do 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.
No segmentation fault, but it does nothing.

I tried functions lua_tolightuserdata, lua_touserdata, lua_tocfunction
but none of them worked.


Thanks for answer and sorry for my english.

With regards,
Jiri Prymus

2009/10/17 Asko Kauppi <[hidden email]>:

> What he needs to do is store the Lua function entry as such (make a copy,
> forget about C pointers) in the Lua registry or a userdata's environment.
> This is a common need and many source codes will carry samples. Then have
> a
> C side common callback which picks up that stored ref to the Lua function
> and executes it. I've made a helper for all this but that code is not
> public.
>
> - asko
>
> On 17.10.2009, at 21.03, Wesley Smith <[hidden email]> wrote:
>
>> I don't completely follow, but you can store arbitrary function pointers
>> as lightuserdata.
>>
>> wes
>>
>> On Oct 17, 2009, at 1:47 AM, Jiří Prymus <[hidden email]> wrote:
>>
>>> Hi,
>>>
>>> I would like to know if there is any chance to convert lua function to
>>> c function. I program a small opencv wrapper and there is one wrapping
>>> function where I need pointer to function. And that's a problem
>>> because I can get only pointer to Lua function and when I convert it
>>> to C function then it does nothing. I know that lua functions are
>>> stored in tables and that's probably why it doesn't work.
>>>
>>> In fact my problem is function gtk_signal_connect(...) where slot
>>> function is my lua function.
>>>
>>> Thanks for answer.
>>>
>>> With regards,
>>> Jiri Prymus
>


Reply | Threaded
Open this post in threaded view
|

Re: Conversion Lua function to C function

Peter Cawley
If you're thinking what I think you are, then it would be an operating
system dependant, and processor architecture (or at least CPU
bytecode) dependant. Note that some 32 versions of Windows (around
NT4?) could run on non-x86 architectures. Linux can do the same.

2009/10/17 GrayFace <[hidden email]>:
> The only way see is to use a platform-dependant hack. For 32 bit Windows I can tell you
> how to do it. It should be easy to tweak it to use it on 32 bit Linux.
Reply | Threaded
Open this post in threaded view
|

Re: Conversion Lua function to C function

Jiří Prymus
In reply to this post by Wesley Smith
So if I understand that, I can't wrapper cvCreateTrackBar function
without re-implementing it in my wrapper, because i'm not able to get
proper Callback function pointer from lua and pass it to opencv
library as a C function pointer.

But it leads to the bypassing original library function and that isn't
too great.

And using hacks isn't proper for me, because it's part of my Bachelor
thesis and I want clear code.

Thanks for help.

With regards,
Jiri Prymus

2009/10/17 Wesley Smith <[hidden email]>:

> I've got a system that allows me to set Lua functions as callback
> actions from GtkMenuItems.  You can find he code here:
>
> // generic interface:
> http://www.mat.ucsb.edu/projects/luaAV/browser/trunk/LuaAV/library/src/LuaAVMenu.cpp
> 471: int MenuItem :: action(lua_State *L)
>
>
> // gtk callback system:
> http://www.mat.ucsb.edu/projects/luaAV/browser/trunk/LuaAV/library/linux/LuaAVMenuLinux.cpp
> 93: void MenuBarImpl :: dispatch(MenuItem *mi)
> 419: void MenuItem :: implEnableAction()
>
>
> wes
>
Reply | Threaded
Open this post in threaded view
|

Re: Conversion Lua function to C function

GrayFace
In reply to this post by Peter Cawley
I'm thinking of the same way window procedures are done in Delphi. Allocate
memory blocks for executtion (VirtualAlloc on Windows, dunno what on Linux.
Maybe even malloc would be fine), write delegates there: write machine code
for call instruction + the parameter to function.
I wasn't correct about 32-bit Windows. I mean 32-bit applications for
Windows. No matter what the real processor is as long as it supports 32-bit
applications. For other architectures it would need different call opcode,
for other systems it would need different memory allocation.
I hoped such thing was in some kind of cross-platform library, but brief
googling hasn't given the needed result. Maybe someone else would be more
lucky.

I personally don't see anything bad in using such hacks except the direct
consiquences of architecture/platform dependance.









----- Original Message -----
From: Peter Cawley
To: Lua list
Sent: Sunday, October 18, 2009 3:19 AM
Subject: Re: Conversion Lua function to C function


If you're thinking what I think you are, then it would be an operating
system dependant, and processor architecture (or at least CPU
bytecode) dependant. Note that some 32 versions of Windows (around
NT4?) could run on non-x86 architectures. Linux can do the same.

2009/10/17 GrayFace <[hidden email]>:
> The only way see is to use a platform-dependant hack. For 32 bit Windows I
> can tell you
> how to do it. It should be easy to tweak it to use it on 32 bit Linux.


Reply | Threaded
Open this post in threaded view
|

Re: Conversion Lua function to C function

Robert G. Jakabosky
On Sunday 18, GrayFace wrote:

> I'm thinking of the same way window procedures are done in Delphi. Allocate
> memory blocks for executtion (VirtualAlloc on Windows, dunno what on Linux.
> Maybe even malloc would be fine), write delegates there: write machine code
> for call instruction + the parameter to function.
> I wasn't correct about 32-bit Windows. I mean 32-bit applications for
> Windows. No matter what the real processor is as long as it supports 32-bit
> applications. For other architectures it would need different call opcode,
> for other systems it would need different memory allocation.
> I hoped such thing was in some kind of cross-platform library, but brief
> googling hasn't given the needed result. Maybe someone else would be more
> lucky.

You could do this with a JIT like LLVM [1] or libjit [2]

[1] http://llvm.org/
[2] http://libjit.com/

--
Robert G. Jakabosky
Reply | Threaded
Open this post in threaded view
|

Re: Conversion Lua function to C function

Francesco Abbate
In reply to this post by Jiří Prymus
Hi,
I think you can do it cleanly. When you use gtk_signal_connect you
should pass lua_State * as a gpointer func_data. As a callback
function you should use a simple C function that you define in your
code, lets call it 'my_callback'.

Then in my_callback you will have access the lua_State * through the
func_data gpointer (you need just a cast). The you need to use
Lua_State to put the Lua function you want in the Lua stack. The
function could be in the Environment, or in the registry or in the
global namespace of even it could already be in the stack. Then you
push the arguments of the Lua functions in the Lua stack and you use
lua_call or lua_pcall.

Anyway, to use this schema the condition is that the GTK main event
loop run  from a C function that was called from Lua. So the schema
could be:
- gtk_signal_connect will be used with some C functions callback that
you prepare on your source code. These functions will look for
particular Lua function and call them
with lua_call
- a Lua function is called to run the GTK main loop, some Lua
functions have been
  prepared in advance in the Environment or in the Lua stack to be
used as callbacks

So we can summarize the call sequence like that:
Lua main code => GTK main loop (C code called from Lua, a Lua stack
will be available) => a C callback is called by GTK main loop (we
still have access to the same Lua stack available for GTK main loop)
=> a lua function is called.

So we have closed the sequence Lua => C code => Lua.

Of course it will be important to clean the stack before the C
callback terminates.

I hope this is clear and pertinent with your problem.

Regards,
Francesco

2009/10/17 Jiří Prymus <[hidden email]>

>
> So if I understand that, I can't wrapper cvCreateTrackBar function
> without re-implementing it in my wrapper, because i'm not able to get
> proper Callback function pointer from lua and pass it to opencv
> library as a C function pointer.
>
> But it leads to the bypassing original library function and that isn't
> too great.
>
> And using hacks isn't proper for me, because it's part of my Bachelor
> thesis and I want clear code.
>
> Thanks for help.
>
> With regards,
> Jiri Prymus
>
> 2009/10/17 Wesley Smith <[hidden email]>:
> > I've got a system that allows me to set Lua functions as callback
> > actions from GtkMenuItems.  You can find he code here:
> >
> > // generic interface:
> > http://www.mat.ucsb.edu/projects/luaAV/browser/trunk/LuaAV/library/src/LuaAVMenu.cpp
> > 471: int MenuItem :: action(lua_State *L)
> >
> >
> > // gtk callback system:
> > http://www.mat.ucsb.edu/projects/luaAV/browser/trunk/LuaAV/library/linux/LuaAVMenuLinux.cpp
> > 93: void MenuBarImpl :: dispatch(MenuItem *mi)
> > 419: void MenuItem :: implEnableAction()
> >
> >
> > wes
> >
Reply | Threaded
Open this post in threaded view
|

Re: Conversion Lua function to C function

Peter Cawley
In reply to this post by GrayFace
On Sun, Oct 18, 2009 at 9:25 AM, GrayFace <[hidden email]> wrote:
> I mean 32-bit applications for Windows. No matter what the real
> processor is as long as it supports 32-bit applications.

My point was that Windows NT 4.0 is a 32 bit operating system (thus
running 32 bit apps) which can run on x86, Alpha, MIPS, or PowerPC.
Thus you would need to support several different architectures, and
not just x86, to fully support this hack for 32 bit Windows
applications.
Reply | Threaded
Open this post in threaded view
|

Re: Conversion Lua function to C function

Jiří Prymus
In reply to this post by Francesco Abbate
Hi,

thanks for great idea.
But I have problem with lua_State *  in my_callback fuction, because
it has only "int pos " as argument .
It's defined like :
typedef void (CV_CDECL *CvTrackbarCallback)(int pos);

And only way to pass stack to callback function is in global variable,
but this isn't so good technique as I hoped.

But yes sample code like this works.

....
lua_State *state;
char funcname[100];

void mycallback(int pos)
{
      lua_pushstring(state,funcname);
      lua_gettable(state,LUA_GLOBALSINDEX);
      lua_pushnumber(state,pos);
      lua_call(state,1,0);
}

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);

  sprintf(funcname,"%s",luaL_checkstring(L,5));
  lua_pushstring(L,funcname);
  lua_gettable(L,LUA_GLOBALSINDEX);
  if (lua_isfunction(L,-1))
   {
      sprintf(funcname,"%s",luaL_checkstring(L,-1));
      state=lua_newthread(L);
    }
 else
    luaL_error(L,"luacv.cvCreateTrackbar(string trackbar_name,string
window_name,int value,int count, name of 'void func(int pos))'");

cvCreateTrackbar(trackbar_name,window_name,&value,count,mycallback);
return 0;
}
....

if  state and funcname are global variables, then it works. But this
way is limited to only one Trackbar widget per script.

Unfortunately I can't use lua_State  in mycallback as you wrote with
gpointer, because
cvCreateTrackbar function is platform depended. Depends on GUI you
use, including WinAPI.


With regards,
Jiri Prymus

2009/10/18 Francesco Abbate <[hidden email]>:

> Hi,
> I think you can do it cleanly. When you use gtk_signal_connect you
> should pass lua_State * as a gpointer func_data. As a callback
> function you should use a simple C function that you define in your
> code, lets call it 'my_callback'.
>
> Then in my_callback you will have access the lua_State * through the
> func_data gpointer (you need just a cast). The you need to use
> Lua_State to put the Lua function you want in the Lua stack. The
> function could be in the Environment, or in the registry or in the
> global namespace of even it could already be in the stack. Then you
> push the arguments of the Lua functions in the Lua stack and you use
> lua_call or lua_pcall.
>
> Anyway, to use this schema the condition is that the GTK main event
> loop run  from a C function that was called from Lua. So the schema
> could be:
> - gtk_signal_connect will be used with some C functions callback that
> you prepare on your source code. These functions will look for
> particular Lua function and call them
> with lua_call
> - a Lua function is called to run the GTK main loop, some Lua
> functions have been
>   prepared in advance in the Environment or in the Lua stack to be
> used as callbacks
>
> So we can summarize the call sequence like that:
> Lua main code => GTK main loop (C code called from Lua, a Lua stack
> will be available) => a C callback is called by GTK main loop (we
> still have access to the same Lua stack available for GTK main loop)
> => a lua function is called.
>
> So we have closed the sequence Lua => C code => Lua.
>
> Of course it will be important to clean the stack before the C
> callback terminates.
>
> I hope this is clear and pertinent with your problem.
>
> Regards,
> Francesco
>
> 2009/10/17 Jiří Prymus <[hidden email]>
>>
>> So if I understand that, I can't wrapper cvCreateTrackBar function
>> without re-implementing it in my wrapper, because i'm not able to get
>> proper Callback function pointer from lua and pass it to opencv
>> library as a C function pointer.
>>
>> But it leads to the bypassing original library function and that isn't
>> too great.
>>
>> And using hacks isn't proper for me, because it's part of my Bachelor
>> thesis and I want clear code.
>>
>> Thanks for help.
>>
>> With regards,
>> Jiri Prymus
>>
>> 2009/10/17 Wesley Smith <[hidden email]>:
>> > I've got a system that allows me to set Lua functions as callback
>> > actions from GtkMenuItems.  You can find he code here:
>> >
>> > // generic interface:
>> > http://www.mat.ucsb.edu/projects/luaAV/browser/trunk/LuaAV/library/src/LuaAVMenu.cpp
>> > 471: int MenuItem :: action(lua_State *L)
>> >
>> >
>> > // gtk callback system:
>> > http://www.mat.ucsb.edu/projects/luaAV/browser/trunk/LuaAV/library/linux/LuaAVMenuLinux.cpp
>> > 93: void MenuBarImpl :: dispatch(MenuItem *mi)
>> > 419: void MenuItem :: implEnableAction()
>> >
>> >
>> > wes
>> >
>
Reply | Threaded
Open this post in threaded view
|

Re: Conversion Lua function to C function

GrayFace
In reply to this post by Peter Cawley
Yes, if the system cannot run x86 applications, then the hack won't work. If
it can, the hack will work.







----- Original Message -----
From: Peter Cawley
To: Lua list
Sent: Sunday, October 18, 2009 8:53 PM
Subject: Re: Conversion Lua function to C function


On Sun, Oct 18, 2009 at 9:25 AM, GrayFace <[hidden email]> wrote:
> I mean 32-bit applications for Windows. No matter what the real
> processor is as long as it supports 32-bit applications.

My point was that Windows NT 4.0 is a 32 bit operating system (thus
running 32 bit apps) which can run on x86, Alpha, MIPS, or PowerPC.
Thus you would need to support several different architectures, and
not just x86, to fully support this hack for 32 bit Windows
applications.


Reply | Threaded
Open this post in threaded view
|

Re: Conversion Lua function to C function

GrayFace
In reply to this post by Jiří Prymus
Instead of 1 you can also have 10 or 100 or 1000 callbacks, but a limited
number of them.
Like,
void mycallback(int pos, int funcid)
{
      luaL_unref(...);
      lua_rawgeti(state, -1, funcid);
      lua_pushnumber(state,pos);
      lua_call(state,1,0);
      lua_pop(state, 1);
}

void mycallback_1(int pos) { mycallback(pos, 1); }
...
void mycallback_100(int pos) { mycallback(pos, 100); }





----- Original Message -----
From: Jiří Prymus
To: Lua list
Sent: Sunday, October 18, 2009 9:25 PM
Subject: Re: Conversion Lua function to C function


Hi,

thanks for great idea.
But I have problem with lua_State *  in my_callback fuction, because
it has only "int pos " as argument .
It's defined like :
typedef void (CV_CDECL *CvTrackbarCallback)(int pos);

And only way to pass stack to callback function is in global variable,
but this isn't so good technique as I hoped.

But yes sample code like this works.

....
lua_State *state;
char funcname[100];

void mycallback(int pos)
{
      lua_pushstring(state,funcname);
      lua_gettable(state,LUA_GLOBALSINDEX);
      lua_pushnumber(state,pos);
      lua_call(state,1,0);
}

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);

  sprintf(funcname,"%s",luaL_checkstring(L,5));
  lua_pushstring(L,funcname);
  lua_gettable(L,LUA_GLOBALSINDEX);
  if (lua_isfunction(L,-1))
   {
      sprintf(funcname,"%s",luaL_checkstring(L,-1));
      state=lua_newthread(L);
    }
 else
    luaL_error(L,"luacv.cvCreateTrackbar(string trackbar_name,string
window_name,int value,int count, name of 'void func(int pos))'");

cvCreateTrackbar(trackbar_name,window_name,&value,count,mycallback);
return 0;
}
....

if  state and funcname are global variables, then it works. But this
way is limited to only one Trackbar widget per script.

Unfortunately I can't use lua_State  in mycallback as you wrote with
gpointer, because
cvCreateTrackbar function is platform depended. Depends on GUI you
use, including WinAPI.


With regards,
Jiri Prymus

2009/10/18 Francesco Abbate <[hidden email]>:

> Hi,
> I think you can do it cleanly. When you use gtk_signal_connect you
> should pass lua_State * as a gpointer func_data. As a callback
> function you should use a simple C function that you define in your
> code, lets call it 'my_callback'.
>
> Then in my_callback you will have access the lua_State * through the
> func_data gpointer (you need just a cast). The you need to use
> Lua_State to put the Lua function you want in the Lua stack. The
> function could be in the Environment, or in the registry or in the
> global namespace of even it could already be in the stack. Then you
> push the arguments of the Lua functions in the Lua stack and you use
> lua_call or lua_pcall.
>
> Anyway, to use this schema the condition is that the GTK main event
> loop run from a C function that was called from Lua. So the schema
> could be:
> - gtk_signal_connect will be used with some C functions callback that
> you prepare on your source code. These functions will look for
> particular Lua function and call them
> with lua_call
> - a Lua function is called to run the GTK main loop, some Lua
> functions have been
> prepared in advance in the Environment or in the Lua stack to be
> used as callbacks
>
> So we can summarize the call sequence like that:
> Lua main code => GTK main loop (C code called from Lua, a Lua stack
> will be available) => a C callback is called by GTK main loop (we
> still have access to the same Lua stack available for GTK main loop)
> => a lua function is called.
>
> So we have closed the sequence Lua => C code => Lua.
>
> Of course it will be important to clean the stack before the C
> callback terminates.
>
> I hope this is clear and pertinent with your problem.
>
> Regards,
> Francesco
>
> 2009/10/17 Jiří Prymus <[hidden email]>
>>
>> So if I understand that, I can't wrapper cvCreateTrackBar function
>> without re-implementing it in my wrapper, because i'm not able to get
>> proper Callback function pointer from lua and pass it to opencv
>> library as a C function pointer.
>>
>> But it leads to the bypassing original library function and that isn't
>> too great.
>>
>> And using hacks isn't proper for me, because it's part of my Bachelor
>> thesis and I want clear code.
>>
>> Thanks for help.
>>
>> With regards,
>> Jiri Prymus
>>
>> 2009/10/17 Wesley Smith <[hidden email]>:
>> > I've got a system that allows me to set Lua functions as callback
>> > actions from GtkMenuItems. You can find he code here:
>> >
>> > // generic interface:
>> > http://www.mat.ucsb.edu/projects/luaAV/browser/trunk/LuaAV/library/src/LuaAVMenu.cpp
>> > 471: int MenuItem :: action(lua_State *L)
>> >
>> >
>> > // gtk callback system:
>> > http://www.mat.ucsb.edu/projects/luaAV/browser/trunk/LuaAV/library/linux/LuaAVMenuLinux.cpp
>> > 93: void MenuBarImpl :: dispatch(MenuItem *mi)
>> > 419: void MenuItem :: implEnableAction()
>> >
>> >
>> > wes
>> >
>


Reply | Threaded
Open this post in threaded view
|

Re: Conversion Lua function to C function

Jiří Prymus
Yes, I know what do you think but this static approach, in  my case
will be better use dynamic algorithm.
But meantime I don't know how to do that.

I want to create algorithm where I can use something like this:

-- lua script--
cv=require('luacv')

function on_trackbar1(pos)
.... some update event stuff..
end

function on_trackbar2(pos)
...another update event stuff for another trackbar widget
end

cv.cvCreateTrackbar(name1,wndname1,edge1,100,"on_trackbar1")
cv.cvCreateTrackbar(name2,wndname2,edge2,100,"on_trackbar2")
-- end of lua --

And that is problem with my current implementation because stack
information and funcname will be rewritten
by second calling of cvCreateTrackbar(....) and C callback function
of first TrackBar will call lua callback function of second TrackBar.

Little confusing, isn't it? :)

With regards,
Jiri Prymus


2009/10/18 GrayFace <[hidden email]>:

> Instead of 1 you can also have 10 or 100 or 1000 callbacks, but a limited
> number of them.
> Like,
> void mycallback(int pos, int funcid)
> {
>     luaL_unref(...);
>     lua_rawgeti(state, -1, funcid);
>     lua_pushnumber(state,pos);
>     lua_call(state,1,0);
>     lua_pop(state, 1);
> }
>
> void mycallback_1(int pos) { mycallback(pos, 1); }
> ...
> void mycallback_100(int pos) { mycallback(pos, 100); }
>
>
>
>
>
> ----- Original Message ----- From: Jiří Prymus
> To: Lua list
> Sent: Sunday, October 18, 2009 9:25 PM
> Subject: Re: Conversion Lua function to C function
>
>
> Hi,
>
> thanks for great idea.
> But I have problem with lua_State *  in my_callback fuction, because
> it has only "int pos " as argument .
> It's defined like :
> typedef void (CV_CDECL *CvTrackbarCallback)(int pos);
>
> And only way to pass stack to callback function is in global variable,
> but this isn't so good technique as I hoped.
>
> But yes sample code like this works.
>
> ....
> lua_State *state;
> char funcname[100];
>
> void mycallback(int pos)
> {
>     lua_pushstring(state,funcname);
>     lua_gettable(state,LUA_GLOBALSINDEX);
>     lua_pushnumber(state,pos);
>     lua_call(state,1,0);
> }
>
> 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);
>
>  sprintf(funcname,"%s",luaL_checkstring(L,5));
>  lua_pushstring(L,funcname);
>  lua_gettable(L,LUA_GLOBALSINDEX);
>  if (lua_isfunction(L,-1))
>  {
>     sprintf(funcname,"%s",luaL_checkstring(L,-1));
>     state=lua_newthread(L);
>   }
> else
>   luaL_error(L,"luacv.cvCreateTrackbar(string trackbar_name,string
> window_name,int value,int count, name of 'void func(int pos))'");
>
> cvCreateTrackbar(trackbar_name,window_name,&value,count,mycallback);
> return 0;
> }
> ....
>
> if  state and funcname are global variables, then it works. But this
> way is limited to only one Trackbar widget per script.
>
> Unfortunately I can't use lua_State  in mycallback as you wrote with
> gpointer, because
> cvCreateTrackbar function is platform depended. Depends on GUI you
> use, including WinAPI.
>
>
> With regards,
> Jiri Prymus
>
> 2009/10/18 Francesco Abbate <[hidden email]>:
>>
>> Hi,
>> I think you can do it cleanly. When you use gtk_signal_connect you
>> should pass lua_State * as a gpointer func_data. As a callback
>> function you should use a simple C function that you define in your
>> code, lets call it 'my_callback'.
>>
>> Then in my_callback you will have access the lua_State * through the
>> func_data gpointer (you need just a cast). The you need to use
>> Lua_State to put the Lua function you want in the Lua stack. The
>> function could be in the Environment, or in the registry or in the
>> global namespace of even it could already be in the stack. Then you
>> push the arguments of the Lua functions in the Lua stack and you use
>> lua_call or lua_pcall.
>>
>> Anyway, to use this schema the condition is that the GTK main event
>> loop run from a C function that was called from Lua. So the schema
>> could be:
>> - gtk_signal_connect will be used with some C functions callback that
>> you prepare on your source code. These functions will look for
>> particular Lua function and call them
>> with lua_call
>> - a Lua function is called to run the GTK main loop, some Lua
>> functions have been
>> prepared in advance in the Environment or in the Lua stack to be
>> used as callbacks
>>
>> So we can summarize the call sequence like that:
>> Lua main code => GTK main loop (C code called from Lua, a Lua stack
>> will be available) => a C callback is called by GTK main loop (we
>> still have access to the same Lua stack available for GTK main loop)
>> => a lua function is called.
>>
>> So we have closed the sequence Lua => C code => Lua.
>>
>> Of course it will be important to clean the stack before the C
>> callback terminates.
>>
>> I hope this is clear and pertinent with your problem.
>>
>> Regards,
>> Francesco
>>
>> 2009/10/17 Jiří Prymus <[hidden email]>
>>>
>>> So if I understand that, I can't wrapper cvCreateTrackBar function
>>> without re-implementing it in my wrapper, because i'm not able to get
>>> proper Callback function pointer from lua and pass it to opencv
>>> library as a C function pointer.
>>>
>>> But it leads to the bypassing original library function and that isn't
>>> too great.
>>>
>>> And using hacks isn't proper for me, because it's part of my Bachelor
>>> thesis and I want clear code.
>>>
>>> Thanks for help.
>>>
>>> With regards,
>>> Jiri Prymus
>>>
>>> 2009/10/17 Wesley Smith <[hidden email]>:
>>> > I've got a system that allows me to set Lua functions as callback
>>> > actions from GtkMenuItems. You can find he code here:
>>> >
>>> > // generic interface:
>>> >
>>> > http://www.mat.ucsb.edu/projects/luaAV/browser/trunk/LuaAV/library/src/LuaAVMenu.cpp
>>> > 471: int MenuItem :: action(lua_State *L)
>>> >
>>> >
>>> > // gtk callback system:
>>> >
>>> > http://www.mat.ucsb.edu/projects/luaAV/browser/trunk/LuaAV/library/linux/LuaAVMenuLinux.cpp
>>> > 93: void MenuBarImpl :: dispatch(MenuItem *mi)
>>> > 419: void MenuItem :: implEnableAction()
>>> >
>>> >
>>> > wes
>>> >
>>
>
>
>
Reply | Threaded
Open this post in threaded view
|

Re: Conversion Lua function to C function

Asko Kauppi
You will find samples of doing this right in other people's code and  
at least one message included links. Read their code. We've given  
enough hints by now, the rest is for you to figure out. This is also  
the only way to really learn something well. Imitate, adopt and then  
teach others.
- asko

On 18.10.2009, at 22.18, Jiří Prymus <[hidden email]> wrote:

> Yes, I know what do you think but this static approach, in  my case
> will be better use dynamic algorithm.
> But meantime I don't know how to do that.
>
> I want to create algorithm where I can use something like this:
>
> -- lua script--
> cv=require('luacv')
>
> function on_trackbar1(pos)
> .... some update event stuff..
> end
>
> function on_trackbar2(pos)
> ...another update event stuff for another trackbar widget
> end
>
> cv.cvCreateTrackbar(name1,wndname1,edge1,100,"on_trackbar1")
> cv.cvCreateTrackbar(name2,wndname2,edge2,100,"on_trackbar2")
> -- end of lua --
>
> And that is problem with my current implementation because stack
> information and funcname will be rewritten
> by second calling of cvCreateTrackbar(....) and C callback function
> of first TrackBar will call lua callback function of second TrackBar.
>
> Little confusing, isn't it? :)
>
> With regards,
> Jiri Prymus
>
>
> 2009/10/18 GrayFace <[hidden email]>:
>> Instead of 1 you can also have 10 or 100 or 1000 callbacks, but a  
>> limited
>> number of them.
>> Like,
>> void mycallback(int pos, int funcid)
>> {
>>     luaL_unref(...);
>>     lua_rawgeti(state, -1, funcid);
>>     lua_pushnumber(state,pos);
>>     lua_call(state,1,0);
>>     lua_pop(state, 1);
>> }
>>
>> void mycallback_1(int pos) { mycallback(pos, 1); }
>> ...
>> void mycallback_100(int pos) { mycallback(pos, 100); }
>>
>>
>>
>>
>>
>> ----- Original Message ----- From: Jiří Prymus
>> To: Lua list
>> Sent: Sunday, October 18, 2009 9:25 PM
>> Subject: Re: Conversion Lua function to C function
>>
>>
>> Hi,
>>
>> thanks for great idea.
>> But I have problem with lua_State *  in my_callback fuction, because
>> it has only "int pos " as argument .
>> It's defined like :
>> typedef void (CV_CDECL *CvTrackbarCallback)(int pos);
>>
>> And only way to pass stack to callback function is in global  
>> variable,
>> but this isn't so good technique as I hoped.
>>
>> But yes sample code like this works.
>>
>> ....
>> lua_State *state;
>> char funcname[100];
>>
>> void mycallback(int pos)
>> {
>>     lua_pushstring(state,funcname);
>>     lua_gettable(state,LUA_GLOBALSINDEX);
>>     lua_pushnumber(state,pos);
>>     lua_call(state,1,0);
>> }
>>
>> 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);
>>
>>  sprintf(funcname,"%s",luaL_checkstring(L,5));
>>  lua_pushstring(L,funcname);
>>  lua_gettable(L,LUA_GLOBALSINDEX);
>>  if (lua_isfunction(L,-1))
>>  {
>>     sprintf(funcname,"%s",luaL_checkstring(L,-1));
>>     state=lua_newthread(L);
>>   }
>> else
>>   luaL_error(L,"luacv.cvCreateTrackbar(string trackbar_name,string
>> window_name,int value,int count, name of 'void func(int pos))'");
>>
>> cvCreateTrackbar(trackbar_name,window_name,&value,count,mycallback);
>> return 0;
>> }
>> ....
>>
>> if  state and funcname are global variables, then it works. But this
>> way is limited to only one Trackbar widget per script.
>>
>> Unfortunately I can't use lua_State  in mycallback as you wrote with
>> gpointer, because
>> cvCreateTrackbar function is platform depended. Depends on GUI you
>> use, including WinAPI.
>>
>>
>> With regards,
>> Jiri Prymus
>>
>> 2009/10/18 Francesco Abbate <[hidden email]>:
>>>
>>> Hi,
>>> I think you can do it cleanly. When you use gtk_signal_connect you
>>> should pass lua_State * as a gpointer func_data. As a callback
>>> function you should use a simple C function that you define in your
>>> code, lets call it 'my_callback'.
>>>
>>> Then in my_callback you will have access the lua_State * through the
>>> func_data gpointer (you need just a cast). The you need to use
>>> Lua_State to put the Lua function you want in the Lua stack. The
>>> function could be in the Environment, or in the registry or in the
>>> global namespace of even it could already be in the stack. Then you
>>> push the arguments of the Lua functions in the Lua stack and you use
>>> lua_call or lua_pcall.
>>>
>>> Anyway, to use this schema the condition is that the GTK main event
>>> loop run from a C function that was called from Lua. So the schema
>>> could be:
>>> - gtk_signal_connect will be used with some C functions callback  
>>> that
>>> you prepare on your source code. These functions will look for
>>> particular Lua function and call them
>>> with lua_call
>>> - a Lua function is called to run the GTK main loop, some Lua
>>> functions have been
>>> prepared in advance in the Environment or in the Lua stack to be
>>> used as callbacks
>>>
>>> So we can summarize the call sequence like that:
>>> Lua main code => GTK main loop (C code called from Lua, a Lua stack
>>> will be available) => a C callback is called by GTK main loop (we
>>> still have access to the same Lua stack available for GTK main loop)
>>> => a lua function is called.
>>>
>>> So we have closed the sequence Lua => C code => Lua.
>>>
>>> Of course it will be important to clean the stack before the C
>>> callback terminates.
>>>
>>> I hope this is clear and pertinent with your problem.
>>>
>>> Regards,
>>> Francesco
>>>
>>> 2009/10/17 Jiří Prymus <[hidden email]>
>>>>
>>>> So if I understand that, I can't wrapper cvCreateTrackBar function
>>>> without re-implementing it in my wrapper, because i'm not able to  
>>>> get
>>>> proper Callback function pointer from lua and pass it to opencv
>>>> library as a C function pointer.
>>>>
>>>> But it leads to the bypassing original library function and that  
>>>> isn't
>>>> too great.
>>>>
>>>> And using hacks isn't proper for me, because it's part of my  
>>>> Bachelor
>>>> thesis and I want clear code.
>>>>
>>>> Thanks for help.
>>>>
>>>> With regards,
>>>> Jiri Prymus
>>>>
>>>> 2009/10/17 Wesley Smith <[hidden email]>:
>>>>> I've got a system that allows me to set Lua functions as callback
>>>>> actions from GtkMenuItems. You can find he code here:
>>>>>
>>>>> // generic interface:
>>>>>
>>>>> http://www.mat.ucsb.edu/projects/luaAV/browser/trunk/LuaAV/library/src/LuaAVMenu.cpp
>>>>> 471: int MenuItem :: action(lua_State *L)
>>>>>
>>>>>
>>>>> // gtk callback system:
>>>>>
>>>>> http://www.mat.ucsb.edu/projects/luaAV/browser/trunk/LuaAV/library/linux/LuaAVMenuLinux.cpp
>>>>> 93: void MenuBarImpl :: dispatch(MenuItem *mi)
>>>>> 419: void MenuItem :: implEnableAction()
>>>>>
>>>>>
>>>>> wes
>>>>>
>>>
>>
>>
>>