#c #ruby #ffi #ruby-ffi
#c #ruby #ffi #ruby-ffi
Вопрос:
В настоящее время я работаю над библиотекой метрик C string и пишу привязки для ruby. Используя ffi, как я могу присоединить функцию с подписью типа char *function(const char *, const char *)
? Рассматриваемая функция выделит строку в куче с помощью malloc
, а затем вернет указатель на эту строку.
Я полагаю, что мне нужно будет обернуть присоединенную к ffi функцию в метод ruby, чтобы я мог преобразовать возвращаемый указатель на строку в строку ruby и освободить старый указатель.
Ответ №1:
Немного поработав и покопавшись в irb
, я выяснил, как безопасно обернуть функцию C, которая возвращает char *
. Сначала необходимо обернуть libc
free
функцию.
module LibC
extend FFI::Library
ffi_lib FFI::Library::LIBC
# attatch free
attach_function :free, [:pointer], :void
end
Теперь, когда у нас есть доступ к free
, мы можем присоединить функцию и обернуть ее в функцию модуля ruby. Я также включил вспомогательный метод для проверки допустимых параметров строки.
module MyModule
class << self
extend FFI::Library
# use ffi_lib to include the library you are binding
def function(str)
is_string(str)
ptr = ffi_function(str)
result = String.new(ptr.read_string)
LibC.free(ptr)
result
end
private
# attach function and alias it as ffi_function
attach_function :ffi_function, :function, [:string], :pointer
# helper to verify strings
def is_string(object)
unless object.kind_of? String
raise TypeError,
"Wrong argument type #{object.class} (expected String)"
end
end
end
end
Вот и все, надеюсь, это поможет кому-нибудь еще, у кого есть подобная проблема.