Как присоединить функцию C, которая возвращает строку с использованием ruby ffi?

#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
  

Вот и все, надеюсь, это поможет кому-нибудь еще, у кого есть подобная проблема.