I'm trying to implement with FFI a few functions from the Darknet library:
require 'ffi'
class Image < FFI::Struct
layout :w, :int
layout :h, :int
layout :c, :int
layout :data, :pointer
end
class Darknet
extend FFI::Library
ffi_lib "./libdarknet.so"
attach_function :load_image_color, [:string, :int, :int], Image
end
image = Darknet.load_image_color("./test.jpg", 0, 0)
It seems that the filename string doesn't get through:
Cannot load image "(null)"
STB Reason: can't fopen
Here are the function and the declaration.
I'm quite new to FFI, but I've managed to implement other functions without any issue. I must be missing something obvious, if someone can give me pointers (no pun intended)...
A Ruby string is not the same as a C
char *
(orchar []
), which is a null-terminated (the last character is ASCII 0 -'\0'
) contiguous array of characters, often considered a "string" in c.Therefore, you will need to convert the ruby string to a pointer, via the macro
StringValueCStr(str)
(wherestr
is the String variable"./test.jpg"
). There is also the option ofStringValuePtr(str)
, which is better in terms of performance, however it is not completely safe, as it does not take into account the fact that c strings are null-terminated, and therefore cannot have null-terminators within the string (which Ruby strings allow).StringValueCStr()
on the other hand does take this into account, and therefore ensures you have a valid c string.