Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 如何不跨实例共享外部变量?_C_Ruby_Ruby C Extension - Fatal编程技术网

C 如何不跨实例共享外部变量?

C 如何不跨实例共享外部变量?,c,ruby,ruby-c-extension,C,Ruby,Ruby C Extension,编辑:这是对问题的改写,因为它以前是如此不具体 因此,在解决C扩展中跨实例共享变量的问题时,我遇到了一个问题。这是我遇到的一个例子 >> t = SCOPE::TestClass.new #=> #<SCOPE::TestClass:0x000001011e86e0> >> t.set = 4 #=> 4 >> t.get #=> 4 >> v = SCOPE::TestClass.new #=> #<SC

编辑:这是对问题的改写,因为它以前是如此不具体

因此,在解决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
或者在C语言中是否有我看不到或不理解的解决方案

代码:

#包括
#包括
价值测试类;
价值范围;
价值检验;
值集(self,val);
值get();
值集(值自身、值val){
测试值=NUM2INT(val);
返回Qnil;
}
值get(){
返回整数(测试变量);
}
void Init_scope()
{
范围=rb_定义_模块(“范围”);
TestClass=rb_定义(范围,“TestClass”,rb_cObject)下的类;
rb_define_方法(TestClass,“set=”,set,1);
rb_define_方法(TestClass,“get”,get,0);
}

全局变量符合彼此共享的ruby c扩展规范(请参阅)。将变量作用域限制在执行任务的最不可见范围是最好的选择。如果您碰巧有一个共享变量,那么至少可以安全地解决同步问题。

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

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

当然,您做了一些错误的事情:ruby必须提供上下文和检索上下文的方法,可能get函数的proto必须至少有值self作为参数,如set。该值不能存储到全局或静态局部变量中:它必须以某种方式存储到对象的“上下文”中。为了知道如何做到这一点,我需要一个关于ruby ext的快速教程。同时,请尝试深入阅读

尤其要注意“访问变量”以及如何定义实例变量

我做了这件事,这似乎奏效了;您可以使用它来实现您的扩展目的(我已经重命名了某些内容,并修复了其他内容;我还删除了INT2NUM和NUM2INT内容,您可以根据需要将其放回原处)

#包括
#包括
价值测试类;
价值范围;
值集(值,值);
值获取(VALUE);
值集(值自身、值val){
(无效)rb_iv_集(自,“@val”,val);
返回Qnil;
}
值获取(值自身){
返回rb_iv_get(self,“@val”);
}
void Init_RubyTest()
{
范围=rb_定义_模块(“RubyTest”);
TestClass=rb_定义(范围,“TestClass”,rb_cObject)下的类;
rb_define_方法(TestClass,“set=”,set,1);
rb_define_方法(TestClass,“get”,get,0);
}

如果我们不知道“C扩展”(我想,到Ruby?)是如何工作的,那么这个问题就无法得到完全的回答,诚恳地说,我也不知道

声明为静态的“全局”变量是定义该变量的文件的局部变量,不能从外部访问,即该变量在该文件内是全局变量,但不是所有链接文件的全局变量

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


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

对不起,如果我创建了C扩展的多个实例,我会发现它们共享外部变量的值。您好,Joerg,在我上面发布的示例中,您是将所有内容都设置为ruby变量,还是有一个我没有看到的C语言解决方案?我想您正在寻找:
VALUE rb\u ivar\u get(VALUE obj,ID ID)
和以下内容:
VALUE rb\u ivar\u set(VALUE obj,ID ID,VALUE val)
#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;
#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);
}