RubyとC。パート3。

過去のパート( パート1パート2 )では、Cを使用してRubyを高速化または拡張することを検討しました。 C / C ++で書かれたプログラムでRubyインタープリターを使用する方法を学びます。
一部のアプリケーションでは、組み込み言語、微調整、または再コンパイルなしの拡張機能の作成が必要になります。 Rubyはこの目的に非常に適しています。 C / C ++にアプリケーションを埋め込むためのシンプルで便利なAPIがあります。 たとえば、Google SketchUpはスクリプト言語としてRubyを使用します。

C / C ++アプリケーションにRubyを埋め込む方法を見てみましょう。


Rubyコードで文字列を実行するrb_eval_string関数を調べることから始めます。
簡単な例を見てみましょう-式を評価するためのプログラム。 簡単にするために、式には2つの変数しかありません。
アプリケーションの例、入力データ:
	 ($ a + $ b)* $ a- $ b
	 2
	 3

結果:
	 ($ a + $ b)* $ a- $ b = 7


コードを見てみましょう:
	 #include <ruby.h>
	 #include <stdio.h>

	 int main(){
		 ruby_init();  //インタプリタの初期化
	
		 int a = 0;
		 int b = 0;
		 char expr [256];
	
		 //式と2つの変数を読み取ります
		 scanf( "%s"、&expr); 
		 scanf( "%d"、&a); 
		 scanf( "%d"、&b);
	
		 // Ruby変数を作成します
		 VALUE r_a = INT2NUM(a);
		 VALUE r_b = INT2NUM(b);
		 //インタプリタで利用可能にします
		 rb_define_variable( "$ a"、&r_a);
		 rb_define_variable( "$ b"、&r_b);
	
		 //式を実行して結果を出力します
		値res = rb_eval_string(expr); 
		 printf( "%s =%d \ n"、expr、NUM2INT(res));

		 0を返します。
	 }

注: VALUEデータ型、INT2NUMマクロなどについて、およびRuby C APIの操作の詳細については、 パート2を参照してください。

この例では、キーボードから2つの変数とそれらの式を読み取ります。 次に、これらの変数に基づいて、グローバルRuby変数を作成し、 rb_define_variableメソッドを使用してインタープリターで使用できるようにしました。
その結果、 rb_eval_stringメソッドを使用して、式を実行し、その結果を画面に表示しました。

それでは、Rubyスクリプトの読み込みと実行に移りましょう。
この例を考えてみましょう。ユーザーアルゴリズムに従って文字列のハッシュを取得する必要があります。 シナリオはこれです。ユーザーはalg.rbファイルを作成し、その中にハッシュアルゴリズムを実装します。 このプログラムでは、ユーザー定義のスクリプトをロードし、それにハッシュ文字列を渡し、スクリプトを実行して、結果を出力します。
コードを見てみましょう:
	 #include <ruby.h>
	 #include <stdio.h>

	 int main(){
		 ruby_init();  //インタプリタの初期化
		 ruby_init_loadpath();  //標準ライブラリを接続する機能。たとえば、「MD5」が必要
		値res = rb_str_new2( "テスト文字列");  //テスト文字列
		 rb_define_variable( "$ res"、&res);  //スクリプトで利用できるようにします
		 rb_load_file( "alg.rb");  //アルゴリズムでファイルをロードします
		 //スクリプトを実行して結果を出力します
		 ruby_exec(); 
		 printf( "%s \ n"、StringValuePtr(res));
		 0を返します。
	 }


これで、alg.rbファイルに任意のハッシュアルゴリズムを実装できます。
たとえば、行内のスペースの数(あまり良いハッシュではありません:)):
	ハッシュ= 0
	 $ res.split(//)。各{| c | ハッシュ+ = 1 if c == ""}
	 $ res = hash.to_s

または、16進数のすべての文字の合計:
	ハッシュ= 0
	 $ res.split(//)。各{| c | ハッシュ+ = c [0]}
	 $ res = hash.to_s(16)

またはmd5、標準ライブラリを使用:
	 「md5」が必要
	 $ res = MD5.hexdigest($ res)


次に、gccなどの埋め込みRubyを使用したアプリケーションのコンパイルについて説明します。
gcc test.c -o test -I< ruby.h> -lruby
どちらか:
gcc test.c -o test -I< ruby.h> -lruby1.8

* nixシステムでコンパイルするには、次のようにruby-devパッケージをインストールする必要があります。
sudo apt-get install ruby1.8-dev

Source: https://habr.com/ru/post/J50039/


All Articles