【问题标题】:What exactly is a gem native extension?究竟什么是 gem 原生扩展?
【发布时间】:2015-07-03 09:01:39
【问题描述】:

我觉得原生扩展就像库一样,您应该在尝试安装依赖于原生扩展的 gem 之前将其安装到系统上。就像ImageMagic 库一样。那是对的吗?关于原生扩展,我们还有什么需要了解的吗?

【问题讨论】:

    标签: ruby rubygems


    【解决方案1】:

    gem 原生扩展可能链接到需要预安装的单独库,RMagick 就是一个例子。

    但是,该术语实际上仅表示“包含一些需要为您的机器编译的代码”。代码被编译和链接,因此生成的可执行文件可以是机器上的 Ruby 的required。

    编写 Ruby C 或 C++ 扩展的通常原因是:

    • 速度。对于一些 CPU 密集型任务,C 代码可以比 Ruby 快 100 倍。在这种情况下,原生扩展可以与 gem 中包含的所有 C 源代码完全独立。

    • 已经用 C 语言编写的第三方库。在这种情况下,gem 将具有将库函数绑定到 Ruby 模块、类和方法中的 C 源代码。

    您可以查看带有本机扩展的 gem 的 C 源代码,它与 Ruby 源代码一起安装。按照惯例,gem 中有一个名为ext/gem_name 的文件夹,其中包含一个Ruby 文件extconf.rb,它将信息传递给编译器(从技术上讲,它创建了一个make file)。此外,C 源文件也放在那里。

    MRI Ruby 在 C 中实现为一个非常“扁平”的结构,基本上由大量 C 函数组成。这使得学习如何实现原生扩展相对容易,即使您不太了解 C。您可以阅读 Extending Ruby 1.9 作为主题介绍。

    本机扩展程序可能无法安装或正常工作。 Stack Overflow 上有很多问题需要帮助解决特定的失败安装问题。常见的问题是:

    • 缺少库。希望 gem 作者会在 README 中解释您需要预安装的内容,但并不总是很清楚。

    • 编译器不匹配。很难测试所有目标系统,所以有时extconf.rb 中的指令在特定系统上不起作用,或者C 代码会因差异而引发警告或无法编译。在 Windows 中,除非您安装 Ruby Devkit

    • ,否则您可能不会有一个可以工作的编译器
    • 不适用于所有版本的 Ruby。例如,JRuby可以使用 C 原生扩展,如果它已启用但并不总是可取的 - 主题相当复杂,但通常避免混合 JRuby 和原生扩展。

      李>

    【讨论】:

    • 感谢您提供如此广泛的答案!我希望看到这样的答案。
    • 很好的答案,虽然我对 MRI api 很容易提出异议:-)
    • @FrederickCheung:与使用 Perl 的 XS 等更深层次的结构相比,IMO 更容易。
    • 关于将 JRuby 与原生扩展混合;如果本机扩展使用 Java,它与使用 CRuby 的本机扩展相同,对吗?或者您在警告中遇到的 JVM 是否有什么特别的事情要避免它?
    • @ebrohman:是的,我认为 java 扩展确实适用于 JRuby,尽管我自己没有开发任何扩展。具体的警告是避免将 C 原生扩展与 JRuby 混合,而我在“主题相当复杂”中含糊地介绍了细节,因为我不了解它的所有来龙去脉
    【解决方案2】:

    Native 扩展只是一个用 C 语言(全部或部分)编写的 gem。

    它可能依赖也可能不依赖外部库,这不是一个因素。重要的是这样的 gem 需要编译并且它可能是平台相关的(有理由使用 C,对吧?也许是为了使用一些低级 OS API 或其他东西。但大多数情况下它是与图书馆)。

    【讨论】:

      【解决方案3】:

      引用this article

      “原生扩展”是将 Ruby gem 与机器上存在的其他一些非 Ruby 软件组件或库连接起来的粘合剂。

      本机扩展不是依赖项。原生扩展通常是与非 Ruby 依赖项交互的 C 代码。

      例如,使用 ImageMagic 的 gem 有一个用 C 编写的本机扩展,它与 ImageMagic 对话并代表从 Ruby gem 到 ImageMagic 的桥梁。

      当您安装 gem 并编译原生扩展时,您不会编译 C 库(例如 ImageMagic),该库必须已经存在于您的系统中。您编译与 gem 捆绑在一起的 C 桥。

      【讨论】:

        【解决方案4】:

        我不是红宝石专家,所以对此持保留态度:

        我相当肯定它只是一个需要安装本机(例如 C-Library)库才能工作的 gem。许多 gem 只是简单地使用 Ruby API 包装现有的 C 库。

        gem 的安装将触发 C 库的下载,然后将使用 gcc 或其他编译器构建这些库。如果不支持您的系统配置,则需要将参数传递给 gem 工具以指示正确的目录等。如果运气不好,您可能需要直接更改 make 文件。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-11-06
          • 2019-02-15
          • 2010-10-04
          • 2014-10-28
          • 2012-08-27
          • 2010-11-12
          • 2011-03-18
          • 2011-01-22
          相关资源
          最近更新 更多