2012-02-15 64 views
0

我正在使用Ruby 1.8上的Ruby-FFI來封裝使用UTF-16LE字符串的庫。該庫有一個返回這樣一個String的C函數。Ruby-FFI(ruby 1.8):讀取UTF-16LE編碼字符串

不管我換功能與

attach_function [:getVersion, [], :pointer] 

,並在返回的指針調用read_string,或者我是否符合

attach_function [:getVersion, [], :string] 

我得到的回覆是隻有第一個字符包起來,因爲第二個字符爲空(\000),結果FFI停止在那裏讀取字符串,顯然是因爲它假定它正在處理一個正常的,單空字符結束的字符串。

有什麼我需要做的,也許在我的Ruby程序或FFI的初始化或其他方式,使它知道我希望字符串是UTF-16LE編碼?我怎麼能解決這個問題?

回答

1

好的,這是迄今爲止(不雅)的解決方法。它涉及到添加一個方法到FFI ::指針。在我的庫中調用應該是安全的,因爲所有的字符串都應該是UTF-16LE編碼的,但否則它可能不會很好,因爲它可能永遠不會遇到雙空字符並且只會繼續讀取內存中字符串的邊界。

module FFI 
    class Pointer 

    # Read string until we encounter a double-null terminator 
    def read_string_dn 
     cont_nullcount = 0 
     offset = 0 
     # Determine the offset in memory of the expected double-null 
     until cont_nullcount == 2 
     byte = get_bytes(offset,1) 
     cont_nullcount += 1 if byte == "\000" 
     cont_nullcount = 0 if byte != "\000" 
     offset += 1 
     end 
     # Return string with calculated length (offset) including terminator 
     get_bytes(0,offset+1) 
    end 

    end 

end