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

В настоящее время я работаю над библиотекой метрик строки C и пишу привязки для ruby. Используя ffi, как я могу прикрепить функцию с такой подписью, как char *function(const char *, const char *)? Рассматриваемая функция будет выделять строку в куче с malloc а затем вернуть указатель на эту строку.

Я полагаю, что мне нужно будет обернуть прикрепленную к ffi функцию в метод ruby, чтобы я мог преобразовать возвращаемый указатель строки в строку ruby ​​и освободить старый указатель.

1 ответ

После небольшой работы и возни в irbЯ понял, как безопасно обернуть функцию C, которая возвращает char *, Сначала надо завернуть libc"s 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

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

Другие вопросы по тегам