I’m having some beginner problems setting an FFI struct in Ruby. What I want to do is pass a pointer to a C string by setting a string property in an FFI::Struct object:
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!
But when I run the code I get this error:
jukebox.rb:44:in `[]=': Cannot set :string fields (ArgumentError) from jukebox.rb:44:in `<main>'
So I don’t really know where to go from here.
Also, if you know of any good documtation or tutorials on this subject please leave a response! So far I have found the wiki documentation on Project Kenai very useful but the more the merrier!
Thanks!
I have tried to declare the string data members as [:char, 5] but that gives another error:
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>
There is a good suggestion to try out the memory pointer type and I will try that after work today.
FFI automatically rejects setting strings. Try changing it from :string to :char_array, as mentioned on this page:
If that doesn’t work, you’re going to have to use a :pointer and convert it back into a string. It’s not well documented, but MemoryPointer has a bunch of available functions, such as
write_string, that should help.