Techioz Blog

Ruby/FFI: 文字列が *char 関数の引数に到達しない

概要

ダークネット ライブラリのいくつかの関数を FFI で実装しようとしています。

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)

ファイル名の文字列が伝わらないようです。

Cannot load image "(null)"
STB Reason: can't fopen

以下に関数と宣言を示します。

私は FFI を初めて使用しましたが、他の機能は問題なく実装できました。誰かが私にヒントを与えてくれれば、明らかな何かが欠けているはずです(冗談ではありません)…

解決策

したがって、マクロ StringValueCStr(str) (str は文字列変数 “./test.jpg”) を使用して、ルビ文字列をポインタに変換する必要があります。 StringValuePtr(str) のオプションもあります。これはパフォーマンスの点で優れていますが、C 文字列は null で終了し、したがって null 終端文字を持つことができないという事実が考慮されていないため、完全に安全というわけではありません。文字列内 (Ruby 文字列では許可されます)。一方、StringValueCStr() はこれを考慮するため、有効な C 文字列が確実に得られます。