lua-users home
lua-l archive

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


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 ****