编辑:这是对问题的重写,因为它之前非常不具体。
所以我在解决 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/