5

I've used the luajit ffi library to wrap a C library that contains a function to draw text on a ppm file:

void drawText(frameBuffer *fb, int px, int py, char* text, pixel color) 

When I try to call it from lua using a string I get this error bad argument #4 to 'drawText' (cannot convert 'string' to 'char *'). It doesn't look like the lua string library has anything to convert entire strings to byte arrays or anything that I could manipulate sufficiently.

Any tips on how I could do this on the lua side without modifying the C code?

BarFooBar
  • 1,086
  • 2
  • 13
  • 32
  • Have you looked at the [documentation for the API](http://www.lua.org/manual/5.2/manual.html#4)? – wallyk Nov 02 '15 at 19:13
  • I'm using the LuaJIT [ffi library](http://luajit.org/ext_ffi.html]) and the documentation there is not quite as helpful. – BarFooBar Nov 02 '15 at 19:22

2 Answers2

11

You cannot pass a Lua string to a ffi function that expects a char* directly. You need to convert the Lua string to a char* first. To do so, create a new C string variable with ffi.new and after that copy the content of your Lua string variable to this new C string variable. For instance:

local text = "text"
-- +1 to account for zero-terminator
local c_str = ffi.new("char[?]", #text + 1)
ffi.copy(c_str, text)
lib.drawText(fb, px, py, c_str, color)
luveti
  • 129
  • 4
  • 15
Diego Pino
  • 11,278
  • 1
  • 55
  • 57
11

Alternatively, rewrite your C function to accept a const char* instead of a char*. Then you can use LuaJIT strings directly, without needing to allocate a buffer for them first.

This means that the function cannot modify the passed string, but you usually don't do that in most functions anyway. It's also required in newer versions of C if you wish to pass in string literals (as they are of the type const char*), and otherwise good API design.

The conversion is documented in the Conversion from Lua objects to C types of the FFI Semantics page.

Colonel Thirty Two
  • 23,953
  • 8
  • 45
  • 85
  • I was in the process of writing the same thing :) You probably don't even have to rewrite your C function, if you know it doesn't modify the string just add `const` to the template in the Lua code (`ffi.cdef`). – catwell Nov 02 '15 at 22:00