【问题标题】:Ruby FFI how to define default argumentsRuby FFI 如何定义默认参数
【发布时间】:2023-03-12 09:09:01
【问题描述】:

我正在尝试将a native extension of ruby 移植到 FFI。暴露的 ruby​​ 接口是

auto_link(text, mode=:all, link_attr=nil, skip_tags=nil, flags=0) { |link_text| ... } 

并且该块是可选的。

原c实现中有两个函数:

int rinku_autolink(
  struct buf *ob,
  const uint8_t *text,
  size_t size,
  autolink_mode mode,
  unsigned int flags,
  const char *link_attr,
  const char **skip_tags,
  void (*link_text_cb)(struct buf *ob, const struct buf *link, void *payload),
  void *payload)

实际工作和

static VALUE rb_rinku_autolink(int argc, VALUE *argv, VALUE self)

它处理默认参数和块回调的东西。

我的问题是,如果我想在 FFI 中公开相同的 ruby​​ 接口,上述哪个函数应该注册到attach_function,还是应该为 FFI 定义另一个 c 函数?以及选择哪个函数如何在attach_function 中定义默认参数值?

【问题讨论】:

    标签: ruby ffi


    【解决方案1】:

    答案是都不是。我认为您误解了 FFI 的观点,或者我误解了您的帖子。如果您将本机扩展移植到 FFI,这应该意味着您将摆脱代码库中的所有 C 代码并将其转换为 Ruby。您应该将旧 C 方法 rinku_autolink()rb_rinku_autolink() 的功能转换为 Ruby,可能是单个 Ruby 方法。然后,如果该 Ruby 方法需要调用一些 C 函数,您可以使用 FFI 的 attach_function 方法来访问这些函数。

    如果这不是您正在做的事情,您能否解释一下您的实际目标是什么以及为什么?

    【讨论】:

    • 我猜你的意思是我应该定义一个名为'auto_link'的新c函数,它完成原始'rinku_autolink'的工作,并且这个函数应该具有与ruby接口相同的参数。那么这个c函数中的默认参数怎么表达呢?
    • 我需要一个 ruby​​ 方法 auto_link(text, mode=:all, link_attr=nil, skip_tags=nil, flags=0) { |link_text| ... },这样我就可以在我的 ruby​​ 代码中调用它,比如auto_link("go http://xxx .") {|link| ...},也可以像 auto_link("go http://xxx .", :another_mode, non_default_link_attr) 一样调用它,我想在 c 中实现这个方法。跨度>
    • 好的。目前在 github.com/vmg/rinku/blob/master/ext/rinku/rinku.c 中实现的方式有什么问题?为什么要使用 FFI?
    • 哦,好的。那么我想说你应该在 C 函数rinku_autolink() 上使用 FFI 的 attach_function 来创建一个私有的 Ruby 方法。然后在 Ruby 中,围绕该 Ruby 方法创建一个小型公共包装器,该方法负责处理参数的默认值。 def autolink(x, y=3, z=4, &block); c_autolink(x,y,z,&block); end
    猜你喜欢
    • 2011-04-22
    • 2018-06-05
    • 1970-01-01
    • 2018-05-27
    • 2021-04-08
    • 2010-12-16
    • 2017-10-16
    • 2019-07-29
    • 1970-01-01
    相关资源
    最近更新 更多