所以,最近我不幸需要为 Ruby 做一个 C 扩展(因为性能)。由于我在理解方面遇到了问题VALUE
(并且仍然存在),所以我查看了 Ruby 源代码并发现:(typedef unsigned long VALUE;
Link to Source,但您会注意到还有其他一些“方法”可以完成,但我认为它本质上是一个long
; 如我错了请纠正我)。因此,在进一步调查时,我发现了一篇有趣的博客文章,其中说:
“...在某些情况下,VALUE 对象可能是数据,而不是指向数据。”
让我感到困惑的是,当我尝试将字符串从 Ruby 传递给 C 并使用(从 RubyRSTRING_PTR();
传递VALUE
给 C 函数),并尝试用它“调试”它strlen();
时返回 4。始终为4。
示例代码:
VALUE test(VALUE inp) {
unsigned char* c = RSTRING_PTR(inp);
//return rb_str_new2(c); //this returns some random gibberish
return INT2FIX(strlen(c));
}
此示例始终返回 1 作为字符串长度:
VALUE test(VALUE inp) {
unsigned char* c = (unsigned char*) inp;
//return rb_str_new2(c); // Always "\x03" in Ruby.
return INT2FIX(strlen(c));
}
有时在 ruby 中,我看到一个异常说“无法将模块转换为字符串”(或类似的东西,但是我一直在弄乱代码,试图弄清楚我现在无法重现该错误当我尝试时会发生错误StringValuePtr();
[我有点不清楚这到底是做什么的。文档说它将传递的参数更改为char*
] on inp):
VALUE test(VALUE inp) {
StringValuePtr(inp);
return rb_str_new2((char*)inp); //Without the cast, I would get compiler warnings
}
因此,有问题的 Ruby 代码是:MyMod::test("blahblablah")
编辑:修正了一些错别字并稍微更新了帖子。
问题
- 究竟是什么
VALUE imp
?指向对象/值的指针?价值本身? - 如果它本身持有价值:它什么时候这样做,有没有办法检查它?
- 我如何实际访问该值(因为我似乎访问了除 该值之外的几乎所有内容)?
PS:我对 C 的理解并不是最好的,但它还在进行中;此外,请阅读代码片段中的注释以获取更多描述(如果有帮助)。
谢谢!