gem 本机扩展到底是什么?

What exactly is a gem native extension?

我觉得本机扩展就像库一样,您应该在尝试安装那些取决于本机扩展的 gem 之前将其安装到系统中。就像 ImageMagic 图书馆。那是对的吗?关于本机扩展,还有什么我们应该了解的吗?

我不是大 ruby 专家,所以对此持保留态度:

我相当确定它只是一个 gem 需要安装本机(例如 C-Library)库才能工作。很多 gem 只是用 Ruby API.

包装现有的 C 库

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

引用 this article

“Native extensions” are the glue that connects a Ruby gem with some other non-Ruby software component or library present on your machine.

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

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

当您安装 gem 并编译本机扩展时,您不会编译 C 库(例如 ImageMagic),该库必须已经存在于您的系统中。您编译与 gem.

捆绑在一起的 C 桥

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

它可能依赖也可能不依赖外部库,这不是这里的一个因素。重要的是这样的 gem 需要编译并且它可能依赖于平台(使用 C 是有原因的,对吧?也许是为了使用一些低级 OS API 之类的。但最常见的是与图书馆进行交互)。

一个gem本机扩展可能link到一个需要预装的独立库,RMagick就是一个例子

然而,该术语实际上仅表示 "includes some code that needs to be compiled for your machine"。代码经过编译和 linked,因此生成的可执行文件可以由 Ruby 在机器上 required。

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

  • 速度。对于一些 CPU-intense 任务,C 代码可以比 Ruby 快 100 倍。在这种情况下,本机扩展可以完全独立于 gem.

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

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

MRIRuby是用C实现的很"flat"的结构,基本上由大量的C函数组成。这使得学习如何实现本机扩展相对容易,即使您不太了解 C。您可以阅读 Extending Ruby 1.9 作为该主题的介绍。

本机扩展可能无法安装或无法正常工作。 Stack Overflow 上有很多问题,寻求有关特定失败安装的帮助。常见的问题是:

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

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

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