Page 1 of 2

Register a C Function array for LUA

Posted: Sat Jul 17, 2010 6:04 pm
by erion
Hello,
I am trying to code an app which interfaces with the LUA interpreter.
Everything works fine, I can execute scripts, etc, register C functions with LUA_Register, however when I try to use the laux function LUAl_register and pass a function array I get a syntax error.
Here's a rough sample code:

Code: Select all

;LUA State
global ls


; The sample procedure

ProcedureC testfunc(L)
  
  MessageRequester("title","success!")
  ProcedureReturn 0
EndProcedure




; Open the Interpreter
  ls=lua_open()
  
  ;Load all the LUA Libs
  luaL_openlibs(ls)
  ;Register the procedures for the interpreter
global dim   EGPFuncs.LUA_Reg(0)
  EGPFuncs(0)\name="testfunc"
; Syntax Error on the Next Line
  EGPFuncs(0)\func(ls)=@testfunc()
;two null values to end the array
  EGPFuncs(FSIndex)\name=""
  EGPFuncs(FSIndex)\func(ls)=#Null

;Execute the sample script
LUAL_DoFile(ls, "script.lua")

  ;Close the interpreter
    lua_close(ls)
The problem, I assume, is that Func has a lua_CFunction type which, as the LUA reference says, needs the Lua_State to be passed, but it is not possible to call a function with an argument, and set an array index at the same time.
Here's how the relevant structure, and the prototype looks like, from the wrapper:

Code: Select all

PrototypeC lua_CFunction 	(L)

Structure luaL_Reg
  name.s
  func.lua_CFunction
EndStructure
In C it can be easily done with an array constructor, as:

Code: Select all

EGPFuncs[] = {{"testfunc"}, {testfunc}};
Since PB has no array constructors of this kind, I'm stuck.
Any help is appreciated.

Erion

Re: Register a C Function array for LUA

Posted: Sat Jul 17, 2010 8:08 pm
by Peyman
every time array must be equal with your number of functions so in this examp must be one and the end of your array everytime must be null.
this must work :

Code: Select all

;LUA State
global ls

; The sample procedure

ProcedureC testfunc(L)
 
  MessageRequester("title","success!")
  ProcedureReturn 0
EndProcedure

; Open the Interpreter
  ls=lua_open()
 
  ;Load all the LUA Libs
  luaL_openlibs(ls)
  ;Register the procedures for the interpreter
global dim   EGPFuncs.LUA_Reg(1)
  EGPFuncs(0)\name = "testfunc"
  EGPFuncs(0)\func = @testfunc()

  EGPFuncs(1)\name = ""
  EGPFuncs(1)\func = #Null

;Execute the sample script
LUAL_DoFile(ls, "script.lua")

  ;Close the interpreter
    lua_close(ls)

Re: Register a C Function array for LUA

Posted: Sat Jul 17, 2010 9:33 pm
by erion
Hello,
Whoops I overlooked that one, thank you a milion! One would assume that if someone codes for 10 years would not make such shameful mistakes, but... :)
Sadly even after fixing it, the code compiles fine, but LUA still does not detect the function (testfunc).
If I'm using lua_register, it works fine.
The function is imported as:

Code: Select all

luaL_register(L,libname.s,rl)
Modifying rl to be a pointer (as *rl) does not help as well.

Erion

Re: Register a C Function array for LUA

Posted: Sun Jul 18, 2010 1:38 pm
by erion
Hello,
I think we are getting somewhere...
As the reference states, if null is passed as the library name, LUA will make the function globally available.
If I do the same, the function is not visible, however if I call it with "test", and say in lua:

Code: Select all

test.testfunc()
it works fine.
So, it seems the array is passed fine, the question is, how to pass a null string?
I've tried #NULL$ and chr(0), but both of them failed.
In case someone's wondering, I'm compiling the exe in non-unicode mode.

Erion

Re: Register a C Function array for LUA

Posted: Sun Jul 18, 2010 2:01 pm
by Pupil
Possibly you need to pass a zero pointer, i.e. not a pointer to an empty string as you do with #NULL$ and Chr(0).

Re: Register a C Function array for LUA

Posted: Sun Jul 18, 2010 2:32 pm
by erion
Pupil wrote:Possibly you need to pass a zero pointer, i.e. not a pointer to an empty string as you do with #NULL$ and Chr(0).
I've tried this:

Code: Select all

global *ptr=#null
; or
global *ptr=0
Then calling the lua_Register function with it, but still, it does not seem to work. Am I doing something wrong?

Erion

Re: Register a C Function array for LUA

Posted: Sun Jul 18, 2010 10:24 pm
by Pupil
What i meant was to call 'luaL_register()' like this:
luaL_register(L, 0, RL)

Re: Register a C Function array for LUA

Posted: Sun Jul 18, 2010 10:29 pm
by erion
Hello,
Sadly it does not work like that as well. LUA is unable to find the test function.

Erion

Re: Register a C Function array for LUA

Posted: Mon Jul 19, 2010 1:38 pm
by Peyman
lua manual says that if you pass second parameter of LuaL_register null so lua declare array as functions and not table so if you pass null you must call your functions without test.XXX and must them just with their name like testfunc() but i dont know its not work any way instead of LuaL_register you can use Lua_register for do it, just use LuaL_register when you want declares functions as table.
for declaring functions use lua_register like this :

Code: Select all

lua_register(L, "testfunc", @testfunc())

Re: Register a C Function array for LUA

Posted: Mon Jul 19, 2010 4:05 pm
by erion
Hello,
The problem is that I have far too many functions to register by calling lua_register, so the array would really be the best option.
Putting it in it's on luba table, (e.g. test.testfunc()) is not a good idea in my project... I'll ask on the LUA forums.

Thanks everyone for your great help, even if my problem is still not solved :)

Erion

Re: Register a C Function array for LUA

Posted: Tue Jul 20, 2010 4:21 am
by Peyman
any way you can use a loop for declaring functions with lua_register like this :

Code: Select all

Procedure LuaL_register2(L, Array funcs.luaL_Reg(1))
  For i = 0 To ArraySize(funcs()) - 1
    lua_register(L, funcs(i)\name, funcs(i)\func)
  Next
EndProcedure

Dim EGPFuncs.luaL_Reg(3)
EGPFuncs(0)\name = "testfunc"
EGPFuncs(0)\func = @testfunc()

EGPFuncs(1)\name = "testfunc2"
EGPFuncs(1)\func = @testfunc2()

EGPFuncs(2)\name = "testfunc3"
EGPFuncs(2)\func = @testfunc3()

EGPFuncs(3)\name = #NULL$
EGPFuncs(3)\func = #Null
  
luaL_register2(L, EGPFuncs())
good luck,
Peyman.

Re: Register a C Function array for LUA

Posted: Tue Jul 20, 2010 6:54 am
by erion
Hi,

This seems nice enough, huge thanks.

Erion

Re: Register a C Function array for LUA

Posted: Sat Aug 14, 2010 9:48 am
by Dave L
Use lua_register() to register functions in the global namespace.

Use luaL_register() to register functions in a user defined namespace (Lua table).

With a few modifications your code works fine.


Dave

Code: Select all

IncludeFile ("lua.pbi")

;LUA State
Global ls

; The sample procedure

ProcedureC testfunc(L)

  MessageRequester("title","success!")
  ProcedureReturn 0
EndProcedure

; Open the Interpreter
  ls=lua_open()

  ;Load all the LUA Libs
  luaL_openlibs(ls)
  ;Register the procedures for the interpreter
Global Dim   EGPFuncs.luaL_Reg(1)
  EGPFuncs(0)\name = "testfunc"
  EGPFuncs(0)\func = @testfunc()

  EGPFuncs(1)\name = ""
  EGPFuncs(1)\func = #Null

luaL_register(ls,"EGP",EGPFuncs())

;Execute the sample script
;LUAL_DoFile(ls, "script.lua")
script.s = "EGP.testfunc()"
luaL_dostring(ls, script)

  ;Close the interpreter
    lua_close(ls)

Re: Register a C Function array for LUA

Posted: Sat Aug 14, 2010 11:03 am
by erion
Hi,
Thanks for the modded code.
Basically the problem is that, despite what the manual says, luaL_register() should work for global functions too. Actually it'd speed up things a bit, since we would not need a loop, just one function call only.
For some odd reason though, this doesn't seem to work as expected...

Erion

Re: Register a C Function array for LUA

Posted: Sat Aug 14, 2010 2:35 pm
by Dave L
Hi Erion,

PureBasic is the challenge here, because you need to pass a nullpointer as second argument for luaL_register(). I don't know how to do this. Maybe this is impossible by design ?

But is this really slowing you down ? Take a look at the Lua source and you will notice that for each element in the array you passed C calls lua_pushcclosure(). This is the same function called by single mode lua_register(). I don't think PB code is slower than C code when iterating over elements in an array.

Thanks for submitting your code in this topic, it really helped me out today.

Dave