0

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)...

1 Answers1

0

A Ruby string is not the same as a C char * (or char []), 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) (where str is the String variable "./test.jpg"). There is also the option of StringValuePtr(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.

schaiba
  • 362
  • 3
  • 11
Ankush
  • 1,061
  • 1
  • 13
  • 22
  • 2
    Your answer seems to apply for a pure C Ruby extension, I'm just trying to make a library wrapper with FFI though... Thanks anyway! – Etienne Jun 19 '18 at 08:12
  • @Etienne Ah, I should have pciked that up from your question. Just to make sure, have you had a look [the FFI examples](https://github.com/ffi/ffi/wiki/Examples)? – Ankush Jun 19 '18 at 08:27