0

I'm trying to print the contents of a null terminated string that is stored in a fixed array. The array is memset'd to zero at the start and then is populated with a null terminated string. I'm attempting to print the string.

This works:

ffi.cdef[[
typedef struct _t
{
    uint16_t i;
    const char * name;
} MyStruct;
]]

ffi.cdef[[
MyStruct* Get();
]]

local myDll = ffi.load("myDll")
local x = myDll.Get()
print("Name: %s", x.name)

This results in an error:

ffi.cdef[[
typedef struct _t
{
    uint16_t i;
    char name[25];
} MyStruct;
]]

ffi.cdef[[
MyStruct* Get();
]]

local myDll = ffi.load("myDll")
local x = myDll.Get()
print("Name: %s", x.name)

The second produces this error:

27: bad argument #2 to 'print' (cannot convert 'char [25]' to 'char (&)[25]')

NOTE: Code was edited from original for this posting without compiling it.

It seems I am improperly handling the array. What is the correct way to do this?

Colonel Thirty Two
  • 23,953
  • 8
  • 45
  • 85
101010
  • 14,866
  • 30
  • 95
  • 172

1 Answers1

0

You can't print c-strings directly with the print function. You need to either convert it to a Lua string first or use the C printf function

print("Name: ", ffi.string(x.name))

or

ffi.C.printf("Name: %s", x.name) -- Note: need to cdecl printf first
Colonel Thirty Two
  • 23,953
  • 8
  • 45
  • 85
  • Also I recommend against replacing builtin functions with functions that work differently; it makes your code confusing to other programmers. This answer assumes you're using the builtin `print` function. – Colonel Thirty Two Nov 05 '14 at 13:12
  • One related question then. How would you recommend shunting all prints to a log file? – 101010 Nov 05 '14 at 13:15
  • Redirect stdout, or use a logging library. If you're have to override print, though, at least make the function use the same arguments; `print` doesn't take a format string, it instead writes each argument with a tab separating them. – Colonel Thirty Two Nov 05 '14 at 13:18
  • @010110110101 I defined my fprintf function like this: `function fprintf(file,fmt,...) file:write(fmt:format(...)) end`. Then you can use it with a file which you get by `local log_file = io.open('log.txt', 'r')` --- `fprintf(log_file, '%s %d', "Hello, world!", 10)`. To redirect stdout, you have to use `io.output`. Make sure you save the original stdout if you want to restore it. You can find an example of redirecting stdin [here](http://www.lua.org/pil/21.2.html) – Ciprian Tomoiagă Nov 28 '14 at 13:03