jmckaskill / luaffi

Standalone FFI library for calling C functions from lua. Compatible with the luajit FFI interface.
469 stars 84 forks source link

Convert string to unsigned char array #26

Closed jamesgraves closed 12 years ago

jamesgraves commented 12 years ago

We can't convert a Lua string to an array of unsigned characters (or other varieties of 8-bit unsigned types like uint8_t).

local ffi = require "ffi"
ffi.cdef[[
int strncmp(const char *s1, const unsigned char *s2, size_t n);
]]
print (ffi.C.strncmp("two", "three", 3))

returns:

lua: unable to convert argument 2 from lua<string> to cdata<const unsigned char*>
stack traceback:
        [C]: in function 'strncmp'
        string_ffi.lua:7: in main chunk
        [C]: in ?

This runs with LuaJIT2, but not with luaffi. I initially stumbled upon this problem when going through the FFI tutorial.

jmckaskill commented 12 years ago

Thanks for the report. Hrrm this is one of those cases where most compilers will balk at you if you try in C. However I'll add a check for it.

jamesgraves commented 12 years ago

I think I was unclear. In the FFI tutorial, they are using compress2() and uncompress() which normally take arguments of the form const uint8_t *. However luaffi won't convert a Lua string to any unsigned character array.

I just used strncmp() because it made for a short example, even though it normally takes char *.

jmckaskill commented 12 years ago

No its me being unclear. The issue is that the pointer cast rules are stricter in luaffi than in luajit at the moment. So string -> const char* (https://github.com/jmckaskill/luaffi/blob/master/ffi.c#L398) which requires an explicit cast to const uint8_t* at the moment (this is because it requires that ct->type matches (https://github.com/jmckaskill/luaffi/blob/master/ffi.c#L498 call to is_same_type). The change I need to make is relax some of the checks in check_typed_pointer to match C rules.

Using an explicit compresse(ffi.cast('uint8_t*', 'my string'),...) should work though.