2011-06-26 4 views
0

編集:以前はあまり特定されていなかったので、これは質問の書き換えです。インスタンス間で外部変数を共有しない方法はありますか?

私は変数が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 

次のコードでの最善の解決策は、単にあなたが

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); 
} 
+3

インスタンスは何ですか? –

+0

申し訳ありませんが、C拡張の複数のインスタンスを作成すると、外部変数の値を共有している状況が発生しています。 – doubleconfess

答えて

1

グローバル変数は、相互間で共有ルビーC拡張(documentationを参照)の仕様に従っています。可変スコープをジョブを実行する最小限の可視に制限するのが最善の選択肢です。共有変数がある場合は、同期問題に対して少なくとも安全である必要があります。

+0

こんにちはJoergさん、上に掲載した例では、すべてをルビ変数にするか、Cで私が見ていない解決法がありますか? – doubleconfess

+0

私はあなたが探していると思う: 'VALUE rb_ivar_get(VALUE obj、ID id)'と以下: 'VALUE rb_ivar_set(VALUE obj、ID id、VALUE val)' – fyr

1

今、私は問題があると思う。あなたの

VALUE test_var; 

は、テストクラスのすべてのインスタンス間で一種の「共有」値です。これはもちろん、新しいインスタンスが作成されるか、メソッドセットが呼び出されるときに上書きされるため、エラーです。したがって、インスタンスを1つだけ持ち、すべてのインスタンスで値を共有することができます。

もちろん、あなたは何か間違っている:Rubyはコンテキストを取得し、それを取得する方法を提供しなければならない。おそらく、get関数のprotoはsetのように少なくともVALUE selfを引数として持つ必要がある。値は、グローバル変数または静的ローカル変数に格納することはできません。オブジェクトの「コンテキスト」に格納する必要があります。それをする方法を知るために、私はruby extについての速いチュートリアルが必要です。その間に、より深くhereを読んでみてください。

特に、「変数へのアクセス」とインスタンス変数の定義方法に注意してください。

私はこれを行っています。それはうまくいくようです。あなたはあなたの拡張目的を達成するためにそれに取り組むことができます(私は何かの名前を変更して別のものを修正しました;また、INT2NUMとNUM2INTのものを削除しました)。

私たちは、「Cの拡張子は」(私はルビーに、仮定?)どのように動作するかわからない場合

この質問

#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); 
} 
は完全にはお答えできません、と心から私は知りません。

静的と宣言された変数は、定義されたファイルに対してローカルであり、外部からはアクセスできない、つまりそのファイル内ではグローバルですが、すべてのリンクされたファイルに対してグローバルではありません。

func1はバーにアクセスできます。シンボルが宣言されるまでシンボルが知られていない(同じ理由でfunc1がfunc2を呼び出すことができないか、少なくともコンパイラが欠落しているプロトタイプに対して警告を出し、func2へのコードはとにかく見つかるから)。しかし、とにかく、いったんシンボルがわかると、それにアクセスすることができます。逆に、変数fooとbarは表示されないので、変数barとfooは外部からは見ることができません(グローバルではありません)。

このコードが共有オブジェクトまたは静的ライブラリとしてコンパイルされることになっている場合、fooおよびbarは、共有オブジェクト/静的ライブラリをリンクするコードでは表示されません。

関連する問題