Register a C Function array for LUA

Just starting out? Need help? Post your questions and find answers here.
erion
Enthusiast
Enthusiast
Posts: 128
Joined: Sun Jan 24, 2010 11:12 pm

Register a C Function array for LUA

Post 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
To see a world in a grain of sand,
And a heaven in a wild flower,
Hold infinity in the palm of your hand,
And eternity in an hour.

- W. B.

Visit my site, also for PureBasic goodies http://erion.tdrealms.com
Peyman
Enthusiast
Enthusiast
Posts: 203
Joined: Mon Dec 24, 2007 4:15 pm
Location: Iran

Re: Register a C Function array for LUA

Post 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)
Sorry for my bad english.
erion
Enthusiast
Enthusiast
Posts: 128
Joined: Sun Jan 24, 2010 11:12 pm

Re: Register a C Function array for LUA

Post 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
To see a world in a grain of sand,
And a heaven in a wild flower,
Hold infinity in the palm of your hand,
And eternity in an hour.

- W. B.

Visit my site, also for PureBasic goodies http://erion.tdrealms.com
erion
Enthusiast
Enthusiast
Posts: 128
Joined: Sun Jan 24, 2010 11:12 pm

Re: Register a C Function array for LUA

Post 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
To see a world in a grain of sand,
And a heaven in a wild flower,
Hold infinity in the palm of your hand,
And eternity in an hour.

- W. B.

Visit my site, also for PureBasic goodies http://erion.tdrealms.com
Pupil
Enthusiast
Enthusiast
Posts: 715
Joined: Fri Apr 25, 2003 3:56 pm

Re: Register a C Function array for LUA

Post 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).
erion
Enthusiast
Enthusiast
Posts: 128
Joined: Sun Jan 24, 2010 11:12 pm

Re: Register a C Function array for LUA

Post 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
To see a world in a grain of sand,
And a heaven in a wild flower,
Hold infinity in the palm of your hand,
And eternity in an hour.

- W. B.

Visit my site, also for PureBasic goodies http://erion.tdrealms.com
Pupil
Enthusiast
Enthusiast
Posts: 715
Joined: Fri Apr 25, 2003 3:56 pm

Re: Register a C Function array for LUA

Post by Pupil »

What i meant was to call 'luaL_register()' like this:
luaL_register(L, 0, RL)
erion
Enthusiast
Enthusiast
Posts: 128
Joined: Sun Jan 24, 2010 11:12 pm

Re: Register a C Function array for LUA

Post by erion »

Hello,
Sadly it does not work like that as well. LUA is unable to find the test function.

Erion
To see a world in a grain of sand,
And a heaven in a wild flower,
Hold infinity in the palm of your hand,
And eternity in an hour.

- W. B.

Visit my site, also for PureBasic goodies http://erion.tdrealms.com
Peyman
Enthusiast
Enthusiast
Posts: 203
Joined: Mon Dec 24, 2007 4:15 pm
Location: Iran

Re: Register a C Function array for LUA

Post 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())
Sorry for my bad english.
erion
Enthusiast
Enthusiast
Posts: 128
Joined: Sun Jan 24, 2010 11:12 pm

Re: Register a C Function array for LUA

Post 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
To see a world in a grain of sand,
And a heaven in a wild flower,
Hold infinity in the palm of your hand,
And eternity in an hour.

- W. B.

Visit my site, also for PureBasic goodies http://erion.tdrealms.com
Peyman
Enthusiast
Enthusiast
Posts: 203
Joined: Mon Dec 24, 2007 4:15 pm
Location: Iran

Re: Register a C Function array for LUA

Post 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.
Sorry for my bad english.
erion
Enthusiast
Enthusiast
Posts: 128
Joined: Sun Jan 24, 2010 11:12 pm

Re: Register a C Function array for LUA

Post by erion »

Hi,

This seems nice enough, huge thanks.

Erion
To see a world in a grain of sand,
And a heaven in a wild flower,
Hold infinity in the palm of your hand,
And eternity in an hour.

- W. B.

Visit my site, also for PureBasic goodies http://erion.tdrealms.com
Dave L
New User
New User
Posts: 6
Joined: Sat Aug 14, 2010 9:27 am

Re: Register a C Function array for LUA

Post 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)
erion
Enthusiast
Enthusiast
Posts: 128
Joined: Sun Jan 24, 2010 11:12 pm

Re: Register a C Function array for LUA

Post 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
To see a world in a grain of sand,
And a heaven in a wild flower,
Hold infinity in the palm of your hand,
And eternity in an hour.

- W. B.

Visit my site, also for PureBasic goodies http://erion.tdrealms.com
Dave L
New User
New User
Posts: 6
Joined: Sat Aug 14, 2010 9:27 am

Re: Register a C Function array for LUA

Post 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
Post Reply