【问题标题】:Ruby Noobie: How to set a string value in an FFI StructRuby Noobie:如何在 FFI 结构中设置字符串值
【发布时间】:2009-04-13 19:46:16
【问题描述】:

我在 Ruby 中设置 FFI 结构时遇到了一些初学者问题。我想要做的是通过在 FFI::Struct 对象中设置字符串属性来传递指向 C 字符串的指针:

class SpSessionConfig < FFI::Struct
  layout :api_version,          :int,
           :cache_location,       :string,
           :settings_location,    :string,
           :application_key,      :pointer,
           :application_key_size, :int,
           :user_agent,           :string,
           :sp_session_callbacks, :pointer,
           :user_data,            :pointer 
  end
end


sessionConf = SpotifyLibrary::SpSessionConfig.new() 
puts sessionConf # => '#<SpotifyLibrary::SpSessionConfig:0x9acc00c>'

sessionConf[:api_version] = 1
puts "Api Version: #{sessionConf[:api_version]}"

myTempDir = "tmp"
sessionConf[:cache_location] = myTempDir # !Error!

但是当我运行代码时,我得到了这个错误:

jukebox.rb:44:in `[]=': Cannot set :string fields (ArgumentError)
from jukebox.rb:44:in `<main>'

所以我真的不知道从这里去哪里。

另外,如果您知道有关此主题的任何好的文档或教程,请留下回复!到目前为止,我在Project Kenai 上找到了 wiki 文档 非常有用,但越多越好!

谢谢!

我试图将字符串数据成员声明为 [:char, 5] 但这又给出了另一个错误:

jukebox.rb:44:in `put': put not supported for FFI::StructLayoutBuilder::ArrayField_Signed8_3 (ArgumentError)
    from jukebox.rb:44:in `[]='
    from jukebox.rb:44:in `<main>

有一个很好的建议可以试试内存指针类型,我今天下班后试试。

【问题讨论】:

  • 我喜欢你的标题。很棒的韵律!

标签: ruby ffi


【解决方案1】:

感谢 Pesto 的回答(已接受),我找到了解决方案。如果缓冲区中有零字节(遵循 c-string 语义),write_string 会提前返回。下面是任何将来可能会遇到此问题的人的代码。

# Open my application key file and store it in a byte array
appkeyfile = File.read("spotify_appkey.key")

# get the number of bytes in the key
bytecount = appkeyfile.unpack("C*").size

# create a pointer to memory and write the file to it
appkeypointer = FFI::MemoryPointer.new(:char, bytecount)
appkeypointer.put_bytes(0, appkeyfile, 0, bytecount)

【讨论】:

    【解决方案2】:

    FFI 自动拒绝设置字符串。尝试将其从 :string 更改为 :char_array,如 this page 所述:

    :char_array - 仅用于结构布局中,其中结构具有 C 样式字符串 (char []) 作为成员

    如果这不起作用,您将不得不使用 :pointer 并将其转换回字符串。它没有很好的文档记录,但 MemoryPointer 有一个 bunch of available functions,例如 write_string,应该会有所帮助。

    【讨论】:

    • 感谢您提供的信息,它确实为我指明了正确的方向。我已经尝试过 :char 数组,但它似乎在 struct 声明中不起作用,请参阅编辑后的问题。
    • 我认为您使用内存指针的建议很划算,今天下班后我会尝试一下并在这里更新。感谢您的帮助。
    猜你喜欢
    • 1970-01-01
    • 2011-01-29
    • 2013-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-21
    相关资源
    最近更新 更多