c - 如何不在实例之间共享外部变量?

标签 c ruby ruby-c-extension

编辑:这是对问题的重写,因为它之前非常不具体。

所以我在解决 C 扩展中的实例之间共享变量的问题时遇到了问题。这是我遇到的示例。

>> t = SCOPE::TestClass.new #=> #<SCOPE::TestClass:0x000001011e86e0>
>> t.set = 4 #=> 4
>> t.get #=> 4
>> v = SCOPE::TestClass.new #=> #<SCOPE::TestClass:0x00000101412bf0>
>> v.set = 5 #=> 5
>> v.get #=> 5
>> t.get #=> 5

下面代码中的最佳解决方案是否是简单地使用您可以设置的 ruby​​ 变量

void rb_define_variable(const char *name, VALUE *var)

或者 C 语言中是否有我没有看到或理解的解决方案?

代码:

#include <stdlib.h>
#include <ruby.h>

VALUE TestClass;
VALUE SCOPE;
VALUE test_var;

VALUE set(self, val);
VALUE get();

VALUE set(VALUE self, VALUE val) {
    test_var = NUM2INT(val);
    return Qnil;
}

VALUE get() {
    return INT2NUM(test_var);
}

void Init_scope() 
{
    SCOPE = rb_define_module("SCOPE");
    TestClass = rb_define_class_under(SCOPE, "TestClass", rb_cObject);

    rb_define_method(TestClass, "set=", set, 1);
    rb_define_method(TestClass, "get", get, 0);
}

最佳答案

好的,现在我想我看到了问题所在。你的

  VALUE test_var;

是测试类的每个实例之间的一种“共享”值。这当然是一个错误,因为它会在创建新实例或调用方法集时被覆盖。因此,您可以只有一个实例,并在每个实例之间共享一个值。

当然,你做错了:ruby 必须提供上下文和检索它的方法,可能 get 函数的原型(prototype)必须至少有 VALUE self 作为参数,就像 set 一样。该值不能存储到全局或静态局部变量中:它必须以某种方式存储到对象的“上下文”中。为了知道如何做到这一点,我需要一个关于 ruby​​ ext 的快速教程。同时尝试更深入地阅读 here .

特别要注意“访问变量”以及如何定义实例变量。

我已经这样做了,看起来有效;您可能想对其进行处理以实现您的扩展目的(我已重命名了某些内容,并修复了其他内容;我还删除了 INT2NUM 和 NUM2INT 内容,您可以根据需要将其放回原处)

#include <stdlib.h>
#include <ruby.h>

VALUE TestClass;
VALUE SCOPE;

VALUE set(VALUE, VALUE);
VALUE get(VALUE);

VALUE set(VALUE self, VALUE val) {
    (void)rb_iv_set(self, "@val", val);
    return Qnil;
}

VALUE get(VALUE self) {
  return rb_iv_get(self, "@val");
}

void Init_RubyTest() 
{
    SCOPE = rb_define_module("RubyTest");
    TestClass = rb_define_class_under(SCOPE, "TestClass", rb_cObject);

    rb_define_method(TestClass, "set=", set, 1);
    rb_define_method(TestClass, "get", get, 0);
}
<小时/>

如果我们不知道“C 扩展”(我想是 Ruby?)如何工作,那么这个问题就无法得到完整的回答,而且我真的不知道。

声明为静态的“全局”变量是定义它的文件的本地变量,无法从外部访问,即它在该文件内是全局的,但对于所有链接的文件来说不是全局的。

func1 确实可以访问 bar;它不能仅仅因为该符号在声明之前是未知的(出于同样的原因 func1 无法调用 func2,或者至少编译器会针对丢失的原型(prototype)发出警告,然后无论如何都会找到 func2 的代码),但无论如何,一旦知道该符号,就可以访问它。相反,这些变量 bar 和 foo 从外部看不到(因此不是全局的),因为符号 foo 和 bar 不可见。

如果此代码应该编译为共享对象或静态库,则链接共享对象/静态库的代码将看不到 foo 和 bar。

关于c - 如何不在实例之间共享外部变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6485689/

相关文章:

c - Far在c语言中是什么意思?

ruby-on-rails - 500内部服务器错误

ruby-on-rails - 目录 : to_json on an array of hashes

ruby - "resources"- ruby​​ gem 目录

图表的 C 库

c - Atmega 切换变量对于 9 位 UART 来说太慢

c - 如何删除数组的第一个元素,并在末尾添加一个新元素?

ruby - 为什么 Ruby 1.9 允许覆盖! !=!〜?

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

c - C 中的 IN 运算符