问题标签 [ruby-c-extension]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
169 浏览

ruby - 使用 NUM2LL 和 NUM2INT 从 Ruby 传递到 C 时修改的数据

我有一个 C 模块,我正在使用 Ruby 测试通过使用这段 C 代码扩展 ruby​​ 来测试它。正在修改 2 ** 24 -1 以上的任何数字。我需要在 Ruby 和 C 之间来回传递 64 位值,它应该是位精确的。任何想法将不胜感激。

. . . 我传递的数据的几个例子:

  • (2^34 -1) * 16 ==> C 接收 (2^34) * 16
  • (2^34 +1) * 16 ==> C 接收 (2^34) * 16
  • (2^24 +1) * 16 ==> C 接收 (2^24) * 16
  • (2^25 -1) ==> C 收到 (2^25)
  • (2^24 -1) ==> C 接收 (2^24 -1) (正确)

下面的任何数字也是正确的。

谢谢!

0 投票
1 回答
200 浏览

ruby - ruby c扩展内部结构

readme.ext作为开发 ruby​​ 扩展的主要资源之一在 ruby​​ 指南中链接,它声明如下:

注意 Ruby 不允许任意指针值成为 VALUE。它们应该是指向 Ruby 所知道的结构的指针。已知结构定义在<ruby.h>.

所以,

  1. 如何在我的对象中保存任意结构而不暴露它?
  2. 是否有比ruby​​ guides中引用的资源更完整的资源?虽然我可以在 ruby​​ C 代码中找到我需要调用的函数,但很难在源代码中找到像上面代码那样的直接答案。

谢谢!

0 投票
2 回答
258 浏览

ruby - 如果我要自己释放内存,我应该使用 ALLOCA_N 吗?

有时您可能需要在不用于对象存储的扩展中分配内存——也许您有一个用于 Bloom 过滤器、图像或一大堆 Ruby 不直接使用的小结构的巨大位图。要正确使用垃圾收集器,您应该使用以下内存分配例程。这些例程比标准 malloc 函数做更多的工作。例如,如果 ALLOC_N 确定它无法分配所需的内存量,它将调用垃圾收集器来尝试回收一些空间。如果不能或请求的内存量无效,它将引发 NoMemError

但是在给定的函数中,我确切地知道何时释放内存。在这种情况下,我还应该使用ALLOC_N分配内存吗?

是否存在我应该自己释放内存的合法案例,或者最好总是使用ALLOC_N它而不关心它?

0 投票
1 回答
138 浏览

ruby - 从 C 扩展创建 Ruby Time 对象

我正在为 Ruby 编写一个 C 扩展,它需要大量使用时间对象。性能对于此应用程序至关重要。我应该如何从 C API 创建 Time 对象以获得最佳性能?我在 ruby​​.h 包含文件中没有找到任何相关的内容。

0 投票
1 回答
419 浏览

ruby - 用于操作二进制数据的 Ruby C 扩展

我需要将 Ruby 与 C 函数接口,该函数在固定大小的缓冲区(16 字节长度)上执行低级字节操作。

我还应该提到,我为此使用了 Ruby 1.8.7,所以 Ruby 试图找出编码并不令人头疼。

如何在我的库中编写 Ruby C 接口代码,以便正确处理字符串中的二进制数据?例如,它对固定长度输入字符串中的零字节具有鲁棒性吗?

如果我使用 StringValuePtr() 它会在零字节处中断。

我想从 Ruby 中调用它,如下所示:

0 投票
1 回答
195 浏览

ruby - 函数的 Ruby C 扩展

我必须为以下功能制作一个 ruby​​ c 扩展Abc_NtkCreateNodeAnd

这是 ruby​​ c 扩展的示例。

现在我的主要问题是如何将指针从 c 传递给 ruby​​。我尝试编写这样的扩展:

Abc_Ntk_t *netw_str = StringValueCStr(netw);我认为代码是错误的。那么正确的代码应该是什么?

0 投票
3 回答
923 浏览

ruby - 如果 gem 安装不支持本机扩展,则回退到纯 Ruby

我正在开发一个 gem,它目前是纯 Ruby,但我也一直在为其中一个特性开发一个更快的 C 变体。该功能在纯 Ruby 中可用,但有时速度较慢。缓慢只会影响一些潜在用户(取决于他们需要哪些功能,以及他们如何使用它们),因此如果 gem 无法在目标系统上编译,它可以优雅地回退到仅 Ruby 的功能是有意义的。

我想在单个 gem 中维护该功能的 Ruby 和 C 变体,并在安装 gem 时提供最佳(即最快)体验。这将使我能够从我的一个项目中支持最广泛的潜在用户。它还将允许其他人的依赖 gem 和项目使用对目标系统的最佳可用依赖项,而不是为了兼容性而使用最低公分母版本。

我希望require在运行时回退出现在主lib/foo.rb文件中,就像这样:

但是,我不知道如何让 gem 安装检查(或尝试失败)本机扩展支持,以便 gem 正确安装,无论它是否可以构建“foo_extended”。当我研究如何做到这一点时,我主要发现了几年前的讨论,例如http://permalink.gmane.org/gmane.comp.lang.ruby.gems.devel/1479http://rubyforge.org/ pipermail/rubygems-developers/2007-November/003220.html暗示 Ruby gems 并不真正支持此功能。不过最近没有什么,所以我希望 SO 上的某个人有一些最新的知识?

我理想的解决方案是在尝试构建扩展之前检测目标 Ruby 不支持(或者在项目级别可能根本不想要)C 本机扩展。但是,如果不太脏,try/catch 机制也可以。

这可能吗,如果可以,怎么办?还是我在搜索时发现的发布两个 gem 变体(例如foo和)的建议仍然是当前的最佳实践?foo_ruby

0 投票
0 回答
106 浏览

ruby - 如何包装 C 函数并传递参数?

我必须Abc_NtkCreateNodeAnd使用 Ruby 包装这个 C 函数:

我写的代码是:

我想使用 Ruby 传递参数并直接调用 C 函数。有可能这样做吗?

0 投票
0 回答
112 浏览

ruby - Integer( :foo ) 和 NUM2INT( :foo ) 在 1.8.7 中意外工作

Integer( param )在 Ruby 和NUM2INT( param )本机扩展中使用它作为接受任何可以在我的公共接口中转换为 Integer 的参数的方式。

最近我遇到了 Ruby 1.8 和 1.9 之间的行为差​​异,其中 1.9 会引发错误,但 1.8 会从Symbolto Fixnum(或 C 中的等价物int)产生不必要的强制:

在 1.9.3 中,我想要的行为:

在 1.8.7 中,我不想要的行为:

这是因为我在发送符号参数而不是整数时在测试中断言了 TypeError,结果我得到了一些 Travis 失败。现在,我已经停止Symbol在我的测试中使用 s 作为错误参数的示例。但是我可以/应该为 1.8.7 兼容性做更多的事情吗?

0 投票
1 回答
2085 浏览

ruby - Ruby 生成的 makefile 不运行

也许这是一个非常明显的答案,但我正在尝试在 Windows 环境中使用 C 扩展 Ruby,当我运行 mingw32-make 时无法进行扩展,它会生成一个名为“forktest-i386-”的文件mingw32.def”,然后说“没有规则来制作目标 'ruby.h',需要 'forktest.o'”。

Forktest 是我正在尝试制作的扩展名。

makefile 是由 ruby​​ 自己的 create_makefile 命令生成的,它真的很复杂,所以我无法对其进行头脑或故事,但无论如何它都在这里: