2012-02-15 2 views
0

Я работаю с Ruby-FFI на Ruby 1.8, чтобы обернуть библиотеку, которая использует строки UTF-16LE. Библиотека имеет функцию C, которая возвращает такую ​​строку.Ruby-FFI (ruby 1.8): чтение кодированных строк UTF-16LE

ли завернуть I функцию с

attach_function [:getVersion, [], :pointer] 

и вызвать read_string возвращаемого указателя, или я обернуть его

attach_function [:getVersion, [], :string] 

Что я получаю обратно только первый символ, потому что второй символ равен null (\000), и, как результат, FFI перестает читать строку там, очевидно, потому что предполагает, что имеет дело с нормальной, единственной нулевой завершенной строкой.

Есть ли что-то, что мне нужно сделать, возможно, при инициализации моей программы Ruby или FFI или иначе, чтобы узнать, что я ожидаю, что строки будут закодированы в UTF-16LE? Как еще я могу обойти это?

ответ

1

ОК, это (неэлегантное) обходное решение, которое у меня есть до сих пор. Это связано с добавлением метода к FFI :: Pointer. Это должно быть безопасно для вызова в контексте моей библиотеки, потому что все строки должны быть закодированы в кодировке 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 
Смежные вопросы