Domanda

Sto avendo alcuni problemi principianti di impostazione di una struct FFI in Ruby. Quello che voglio fare è passare un puntatore a una stringa C impostando una proprietà di stringa in un FFI :: oggetto Struct:

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!

Ma quando ho eseguito il codice ottengo questo errore:

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

Quindi non so davvero dove andare da qui.

Inoltre, se siete a conoscenza di qualsiasi bene documtation o tutorial su questo argomento si prega di lasciare una risposta! Finora ho trovato la documentazione wiki su Progetto Kenai  molto utile, ma più siamo meglio è!

Grazie!

Ho cercato di dichiarare i membri di dati stringa come [: char, 5], ma che dà un altro errore:

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>

Non è una buona idea per provare il tipo di puntatore di memoria e cercherò che dopo il lavoro di oggi.

È stato utile?

Soluzione

FFI rifiuta automaticamente l'impostazione stringhe. Prova a cambiare da: stringa da: char_array, come indicato sul questa pagina :

  

: char_array - utilizzato solo in un layout struct cui struttura ha una stringa in stile C (char []) come membro

Se questo non funziona, si sta andando ad avere per usare un: puntatore e convertirlo in una stringa. Non è ben documentato, ma MemoryPointer ha un gruppo di funzioni disponibili , come write_string, che dovrebbe aiutare.

Altri suggerimenti

Quindi, grazie alla risposta da Pesto (accettati) Ho trovato una soluzione. write_string ritorni presto se c'è un byte zero nel buffer (segue semantica c-stringa). Ecco il codice per chiunque possa inciampare su questo problema in futuro.

# 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)
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top