[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: about luaffi
- From: Martin Krpan <wtxnh-lua@...>
- Date: Fri, 14 Sep 2012 00:57:01 +0200
On Wed, Sep 12, 2012 at 10:31:21PM +1000, Daurnimator wrote:
> You need to pass n in a table.
>
> local buflen = ffi.new("unsigned long[1]", {n})
Thank you, that helped! I also had to use explicit cast in next line:
local res = zlib.compress2(buf, buflen, ffi.cast('const unsigned char*', txt), #txt, 9)
otherwise I got an error:
lua: unable to convert argument 3 from lua<string> to cdata<const unsigned char*>
Now I have another problem. In C library I have function that takes tree
arguments: string, calback funtion and void* data.
This void* data is than passed to callback function when it is called.
Here are C declarations of this function and callback function:
typedef void (*PHYSFS_EnumFilesCallback)(void *data, const char *origdir,
const char *fname);
void PHYSFS_enumerateFilesCallback(const char *dir,
PHYSFS_EnumFilesCallback c,
void *d);
I can call PHYSFS_enumerateFilesCallback function and pass it Lua function
as callback but void* pointer can only be ffi.C.NULL or Lua string.
I am doing it like this:
voidp = ffi.typeof('void*')
local dp
dp = voidp('this works') -- This is line 32
If I try to pass number to that function I get error:
dp = voidp(2) -- This is line 32
lua: unable to convert argument 2 from lua<number> to cdata<pointer>
stack traceback:
[C]: in function 'voidp'
testphysfs.lua:32: in main chunk
[C]: ?
For table the error is:
dp = voidp({x=10; y=20}) -- This is line 32
lua: testphysfs.lua:32: Can't set a pointer member to a struct that's about to be freed
stack traceback:
[C]: in function 'voidp'
testphysfs.lua:32: in main chunk
[C]: ?
How can I pass table (for example) to my Lua callback function?
And how do I dereference void* pointer back to lua table in callback function?
When I pass string as void* I have to dereference like this:
local str = ffi.string(ffi.cast('char*', data))
How to do it for table? (or number, or Lua function, or ...)
Martin
Bellow is example that works as expected when string is used as argument:
**** testphysfs.lua ****
local ffi = require('ffi')
function printf(...)
return print(string.format(...))
end
ffi.cdef(io.open('ffi_physfs.h', 'r'):read('*a'))
ph=ffi.load('physfs')
local rc
rc = ph.PHYSFS_init(arg[-1])
rc = ph.PHYSFS_mount(arg[1], '/', 0)
function cb_func(data, origdir, fname)
if data ~= ffi.C.NULL then
local str = ffi.string(ffi.cast('char*', data))
printf("%#d:%s:", #str, str)
end
printf("[%s] %s", ffi.string(origdir), ffi.string(fname))
end
cb = ffi.cast('PHYSFS_EnumFilesCallback', cb_func)
ph.PHYSFS_enumerateFilesCallback( '/', cb, ffi.C.NULL )
print'======== separator ========'
cb_data = {x=10; y=20}
voidp = ffi.typeof('void*')
local dp
-- dp = ffi.cast('void *', cb_data)
-- dp = voidp(cb_data)
dp = voidp('this works') -- This is line 32
ph.PHYSFS_enumerateFilesCallback( "/", cb, dp)
cb:free()
**** end of testphysfs.lua ****
**** output ****
$ lua testphysfs.lua dynasm.zip
[/] dasm_arm.h
[/] dasm_arm.lua
[/] dasm_ppc.h
[/] dasm_ppc.lua
[/] dasm_proto.h
[/] dasm_x64.lua
[/] dasm_x86.h
[/] dasm_x86.lua
[/] dynasm.lua
======== separator ========
10:this works:
[/] dasm_arm.h
10:this works:
[/] dasm_arm.lua
10:this works:
[/] dasm_ppc.h
10:this works:
[/] dasm_ppc.lua
10:this works:
[/] dasm_proto.h
10:this works:
[/] dasm_x64.lua
10:this works:
[/] dasm_x86.h
10:this works:
[/] dasm_x86.lua
10:this works:
[/] dynasm.lua
**** end of output ****