Ruby_extLib 2 - gfd-dennou-club/mrubyc-esp32 GitHub Wiki
[æºå] C èšèªã§ Ruby æ¡åŒµã©ã€ãã©ãªã®äœæ
Ruby ã®ã¢ãžã¥ãŒã«ãã¯ã©ã¹ã C èšèªã§æžãããšãã§ããïŒ é«éã«åŠçãããéšåã C èšèªã§å®è£ ããããšã¯è¯ãããããšã§ããïŒ
åæºå (Linux ã®å Žå)
C ã³ã³ãã€ã©
Ruby ã®ã³ã³ãã€ã«ã«çšãããã®ãšåããã®ãå¿ èŠãšãªãïŒDebian (Linux) ã§ã¯ gcc ã䜿ãããŠããã®ã§ïŒgcc ããã±ãŒãžãã€ã³ã¹ããŒã«ããŠããã°è¯ãïŒ
ruby.h, mkmf.rb
Ruby ããœãŒã¹ã³ãŒãããèªåã§ãã«ãããå Žåã¯ã€ã³ã¹ããŒã«ãããŠãããïŒ ãã€ããªããã±ãŒãžãå°å ¥ããå Žåã«ã¯ ruby.h ã mkmf.rb ãã€ã³ã¹ããŒã«ãããŠããã確èªããããšïŒ Debian (Linux) ã§ã¯ ruby.h ã mkmf.rb ã¯éçºçšããã±ãŒãžã§æäŸãããŠããã®ã§ïŒ apt install ã³ãã³ãã§ ruby-dev ããã±ãŒãžãã€ã³ã¹ããŒã«ããã°è¯ãïŒ
$ sudo apt update
$ sudo apt install ruby-dev
åæºå (Windows11 ã®å Žå)
Ruby ã®éçºããã (DevKit) ä»ãããã±ãŒãžãã€ã³ã¹ããŒã«ããå¿ èŠãããïŒãã®éçºãããã« mruby.h ã ãã§ãªãïŒã³ã³ãã€ã«ã«äœ¿ã gcc ã make ãªã©ãå«ãŸããŠããïŒã€ã³ã¹ããŒã«ã«ã¯äž»ã« 2 ã€ã®ããæ¹ãããïŒ
-
RubyInstaller for Windows ã® Web (https://rubyinstaller.org/downloads/) ãã "Ruby + DevKit" ãšæžãããã€ã³ã¹ããŒã©ãŒãããŠã³ããŒãããŠå©çšãã
-
PowerShell äžã§ winget ã³ãã³ãã§ "Ruby x.x with MSYS2" ãšæžãããããã±ãŒãžãã€ã³ã¹ããŒã«ãã
以äžã§ã¯ winget ãå©çšããã±ãŒã¹ã«ã€ããŠè©³èª¬ããïŒãŸãããã±ãŒãžã® ID ã確èªããïŒ"with MSYS2" ã® ID åãæ§ããïŒ
> winget search ruby
åå ID ããŒãžã§ã³ äžèŽ ãœãŒã¹
---------------------------------------------------------------------------------------
(...ç¥...)
Ruby 3.4 RubyInstallerTeam.Ruby.3.4 3.4.9-1 Command: ruby winget
Ruby 4.0 RubyInstallerTeam.Ruby.4.0 4.0.5-1 Command: ruby winget
(...ç¥...)
Ruby 3.4 with MSYS2 RubyInstallerTeam.RubyWithDevKit.3.4 3.4.9-1 Command: ruby winget
Ruby 4.0 with MSYS2 RubyInstallerTeam.RubyWithDevKit.4.0 4.0.5-1 Command: ruby winget
(...ç¥...)
次ã«ïŒID ãæå®ãã圢㧠winget ã³ãã³ãã§ã€ã³ã¹ããŒã«ããïŒ
> winget install --id RubyInstallerTeam.RubyWithDevKit.4.0
ãã®éçºç°å¢ã«ã¯ GNU make ãªã©å«ãŸããŠããïŒruby.h ãåŒã¶å Žåãªã©ã¯åã« make ãšæã€ã®ã§ã¯ãªãïŒ
$ ridk exec make
ãšããªããšãããªãïŒããããªããšãã¹ãçã£ãŠã³ã³ãã€ã«ã«å€±æããïŒ
è£è¶³ïŒæ¢ã« Ruby ããã±ãŒãžãå ¥ã£ãŠããå Žå
åºæ¬çã«æåŸã«ã€ã³ã¹ããŒã«ããããã±ãŒãžãå©çšãããïŒè€æ°ã€ã³ã¹ããŒã«ãããŠããå Žåã¯ïŒ 以äžã®ããã«çŸåšå©çšããŠãã Ruby ã®ã€ã³ã¹ããŒã«å Žæã調ã¹ãŠã¿ããšè¯ãïŒ
> where.exe ruby
> ruby -e "puts RbConfig::TOPDIR"
ãŸãïŒæ¢ã«å ¥ã£ãŠãã Ruby ããã±ãŒãžã®å®äœã調ã¹ãã«ã¯ä»¥äžã®ã³ãã³ãã§ææ¡ã§ããïŒ
> winget list --query Ruby
ãã® winget list --query Ruby ã³ãã³ãã§ Ruby ã衚瀺ããããïŒããã±ãŒãžåã« "withDevKit" ãä»ããŠããªãå Žåã¯ïŒéçºãããã®ã€ã³ã¹ããŒã«ãå¿ èŠãšãªãïŒ çŸåšã®ããã±ãŒãžã winget uninstall --id RubyInstallerTeam.Ruby.4.0 ã®ããã«åé€ããŠå ¥ãçŽããŠãè¯ããïŒ ä»¥äžã®ã³ãã³ãã§ DevKitïŒMSYS2ïŒã®è¿œå ã€ã³ã¹ããŒã«ãããã®ãç°¡åã§ããïŒ
> ridk install
å©çšãã颿°
ã¢ãžã¥ãŒã«ãšã¯ã©ã¹ã¯äžèŠäŒŒãŠãããïŒã¯ã©ã¹ãããŒã¿ãšåŠçãäžã€ã«ãŸãšãããã®ã«å¯ŸããŠïŒã¢ãžã¥ãŒã«ã¯åŠçã ãããŸãšãããã®ïŒãšèšããïŒå ·äœçã«ã¯ä»¥äžã®ãããªéããããïŒ
- ã¢ãžã¥ãŒã«ã¯ã€ã³ã¹ã¿ã³ã¹ãäœããªã
- ã¢ãžã¥ãŒã«ã¯ç¶æ¿ã§ããªã
ã¢ãžã¥ãŒã«ãå®çŸ©ããå Žå
ã¢ãžã¥ãŒã«ãäœæããã«ã¯ä»¥äžã®é¢æ°ãçšããïŒ
VALUE rb_define_module(const char *name);
- åŒæ°ã¯ã¢ãžã¥ãŒã«ã®åå
- VALUE åæ§é äœã¯ Ruby ã®ãªããžã§ã¯ããæ ŒçŽããŠããæ§é äœ
C èšèªã®é¢æ°ã Ruby ã®ã¢ãžã¥ãŒã«é¢æ°ãšããŠç»é²ããã«ã¯ããã€ãã®æ¹æ³ããããïŒ ä»¥äžãæãç°¡åã§ããïŒ
void rb_define_module_function(VALUE module, const char *name, VALUE (*func)(), int argc);
- 第 1 åŒæ°ïŒé¢æ°ã远å ããã¢ãžã¥ãŒã«ãæ ŒçŽããVALUEåæ§é äœ
- 第 2 åŒæ°ïŒRuby ã«ãããã¡ãœããå
- 第 3 åŒæ°ïŒå®éã«åŒã³åºã C èšèªã®é¢æ°ãäžããïŒé¢æ°ã®å㯠VALUE åïŒ
- 第 4 åŒæ°ïŒåŒã³åºã颿°ã®åŒæ°ã®æ°ïŒself ãšãããªããžã§ã¯ãã第 1 åŒæ°ãšããŠæž¡ãããããã ã©ãããŒé¢æ°ã«å®éã«æž¡ãããåŒæ°ã®æ°ã¯ãããã 1 ã€å€ããªãïŒ
ã¯ã©ã¹ãå®çŸ©ããå Žå
ã¢ãžã¥ãŒã«ãäœæããã«ã¯ä»¥äžã®é¢æ°ãçšããïŒããã¯ã¯ã©ã¹ super ã®äžäœã¯ã©ã¹ name ãäœæãããšããæå³ã§ããïŒ
VALUE rb_define_class(const char *name, VALUE super);
- 第 1 åŒæ°ïŒã¢ãžã¥ãŒã«ã®åå
- 第 2 åŒæ°ïŒäžäœã¯ã©ã¹
- VALUE åæ§é äœã¯ Ruby ã®ãªããžã§ã¯ããæ ŒçŽããŠããæ§é äœ
C èšèªã®é¢æ°ã Ruby ã®ã¯ã©ã¹ã¡ãœãããšããŠç»é²ããïŒ
void rb_define_method(VALUE class, const char *name, VALUE (*func)(), int argc);
- 第 1 åŒæ°ïŒé¢æ°ã远å ããã¯ã©ã¹ãæ ŒçŽãã VALUE åæ§é äœ
- 第 2 åŒæ°ïŒRuby ã«ãããã¡ãœããå
- 第 3 åŒæ°ïŒå®éã«åŒã³åºã C èšèªã®é¢æ°ãäžããïŒé¢æ°ã®å㯠VALUE åïŒ
- 第 4 åŒæ°ïŒåŒã³åºã颿°ã®åŒæ°ã®æ°ïŒself ãšãããªããžã§ã¯ãã第 1 åŒæ°ãšããŠæž¡ãããããã ã©ãããŒé¢æ°ã«å®éã«æž¡ãããåŒæ°ã®æ°ã¯ãããã 1 ã€å€ããªãïŒ
æ¡åŒµã©ã€ãã©ãªäœæã®å ·äœäŸ (1) : "Hello World"
æ¡åŒµã©ã€ãã©ãªå : ã¢ãžã¥ãŒã«ç
"Hello World" ãåºåããããã°ã©ã ãäœæããïŒ ããã§ã¯ C èšèªã§ Greeter ãšããåã®ã¢ãžã¥ãŒã«ãå®çŸ©ãïŒ ããã« hello ãšããã¡ãœãããå ããããšã«ããïŒ hello ã¡ãœããã®äžèº«ãåè¿°ã® hello.c ãšåæ§ãªå 容ãšããïŒ
$ mkdir -p ~/ruby-extlib/02
$ cd ~/ruby-extlib/02
C èšèªã§ã¢ãžã¥ãŒã«ãå®çŸ©ããå Žåã¯ïŒä»¥äžã®ããã«ããã°ã©ã (hello1.c) ãæžãæããïŒ
#include "ruby.h" // ruby.h ã®ã€ã³ã¯ã«ãŒãã¯å¿
é
/* C èšèªã§ã® "Hello World"*/
void c_hello(){
printf("Hello, world!\n");
}
//ã©ãããŒé¢æ°
// * 颿°ã®åã¯åžžã« VALUE
// * 颿°ã®åŒæ°ã®åã¯åžžã« VALUEïŒç¬¬äžåŒæ°ã®åå㯠self ã«ããŠããããšïŒ
// * ä»ã¯ç¹ã«äœãæ»ãå€ãå¿
èŠã§ãªãã®ã§ïŒRubyã®ãnilã㫠察å¿ãããQnilããšãã宿°ãäžããŠããïŒ
VALUE ruby_hello(VALUE self){
c_hello();
return Qnil;
}
//ã©ã€ãã©ãªã®åæå颿°
// * Ruby ã¯ã©ã€ãã©ãªãèªã¿èŸŒãã ããŸã ãInit_ã©ã€ãã©ãªåã ãšãã颿°ãå®è¡ããããïŒä»å㯠Init_greeter ãšããïŒ
// * 颿°ã®åã¯åžžã« void
// * rb_define_module ã§ã¢ãžã¥ãŒã«åãå®ãã
// * Ruby ã§ã¯ã¢ãžã¥ãŒã«åã®å
é ã¯å€§æåã«ããã®ã§ Greeter ãšãã (äžæ¹ã§ïŒãã¡ã€ã«åãªã©ã¯å
šéšå°æåã§è¯ãã)ïŒ
// * rb_define_module_function ã§ã¡ãœããåãšïŒã¡ãœããåã«å¯Ÿå¿ããã©ãããŒé¢æ°åãç»é²ããïŒ
void Init_greeter(){
VALUE module = rb_define_module("Greeter");
rb_define_module_function(module, "hello", ruby_hello, 0);
}
ãã® hello1.c ããã°ã©ã ãã³ã³ãã€ã«ããïŒRuby ã«ã¯æ¡åŒµã©ã€ãã©ãªãã³ã³ãã€ã«ããããã® Makefile ãäœãä»çµã¿ãããã®ã§ïŒãããå©çšããïŒ ãã®ããã«ïŒãŸãïŒå¿ èŠãªãœãŒã¹ã³ãŒãã 1 ã€ã®ãã£ã¬ã¯ããªã«ãŸãšãïŒ åããã£ã¬ã¯ããªã« extconf.rb ãšããååã®ãã¡ã€ã«ãäœãïŒ
extconf.rb ã以äžã®ããã«æžãïŒãã® extconf.rb ã§ã¯ greeter ãšããååã§æ¡åŒµã©ã€ãã©ãªãäœãããã® Makefile ãäœæããããã«æç€ºããŠããïŒ
require "mkmf"
create_makefile("greeter")
次ã«ïŒMakefileãäœãããã« extconf.rb ãå®è¡ãïŒããã« make ããïŒ
$ ruby extconf.rb
$ make (Windows11 ã®å Žåã¯ïŒridk exec make)
$ ls
Makefile extconf.rb greeter.so hello1.c hello1.o
extconf.rb å ã§ greeter ãäœãããæå®ããŠããã®ã§ make ããçµæãšã㊠greeter.so ãäœæãããïŒ ããã Ruby ããå®è¡ããŠã¿ãïŒ main1.rb ã以äžã®ããã«æžãïŒ
require "./greeter" #greeter.so ã䜿ãããã«
Greeter.hello #ã€ã³ã¹ã¿ã³ã¹ãäœããã«ã¡ãœãããå®è¡å¯
main1.rb ãå®è¡ããïŒ
$ ruby main1.rb
Hello, world! (<-- ç¡äºã«åºåããã)
æ¡åŒµã©ã€ãã©ãªå : ã¯ã©ã¹ç
"Hello World" ãåºåããããã°ã©ã ãäœæããïŒ ããã§ã¯ C èšèªã§ Greeter ãšããåã®ã¯ã©ã¹ãå®çŸ©ãïŒ ããã« hello ãšããã¡ãœãããå ããããšã«ããïŒ hello ã¡ãœããã®äžèº«ãåè¿°ã® hello.c ãšåæ§ãªå 容ãšããïŒ
$ mkdir -p ~/ruby-extlib/03
$ cd ~/ruby-extlib/03
C èšèªã§ã¯ã©ã¹ãå®çŸ©ããå Žåã¯ïŒä»¥äžã®ããã«ããã°ã©ã (hello2.c) ãäœæããïŒ
#include "ruby.h" // ruby.h ã®ã€ã³ã¯ã«ãŒãã¯å¿
é
/* C èšèªã§ã® "Hello World"*/
void c_hello(){
printf("Hello, world!\n");
}
//ã©ãããŒé¢æ°
// * 颿°ã®åã¯åžžã« VALUE
// * 颿°ã®åŒæ°ã®åã¯åžžã« VALUEïŒç¬¬äžåŒæ°ã®åå㯠self ã«ããŠããããšïŒ
// * ä»ã¯ç¹ã«äœãæ»ãå€ãå¿
èŠã§ãªãã®ã§ïŒRubyã®ãnilã㫠察å¿ãããQnilããšãã宿°ãäžããŠããïŒ
VALUE ruby_hello(VALUE self){
c_hello();
return Qnil;
}
//ã©ã€ãã©ãªã®åæå颿°
// * Ruby ã¯ã©ã€ãã©ãªãèªã¿èŸŒãã ããŸã ãInit_ã©ã€ãã©ãªåã ãšãã颿°ãå®è¡ããããïŒä»å㯠Init_greeter ãšããïŒ
// * 颿°ã®åã¯åžžã« void
// * rb_define_class ã§ã¯ã©ã¹åãå®ãã
// * Ruby ã§ã¯ã¯ã©ã¹åã®å
é ã¯å€§æåã«ããã®ã§ Greeter ãšãã (äžæ¹ã§ïŒãã¡ã€ã«åãªã©ã¯å
šéšå°æåã§è¯ãã)ïŒ
// * rb_define_method ã§ã¡ãœããåãšïŒã¡ãœããåã«å¯Ÿå¿ããã©ãããŒé¢æ°åãç»é²ããïŒ
void Init_greeter(){
VALUE class = rb_define_class("Greeter", rb_cObject);
rb_define_method(class, "hello", ruby_hello, 0);
}
ãã® hello2.c ããã°ã©ã ãã³ã³ãã€ã«ããïŒRuby ã«ã¯æ¡åŒµã©ã€ãã©ãªãã³ã³ãã€ã«ããããã® Makefile ãäœãä»çµã¿ãããã®ã§ïŒãããå©çšããïŒ ãã®ããã«ïŒãŸãïŒå¿ èŠãªãœãŒã¹ã³ãŒãã 1 ã€ã®ãã£ã¬ã¯ããªã«ãŸãšãïŒ åããã£ã¬ã¯ããªã« extconf.rb ãšããååã®ãã¡ã€ã«ãäœãïŒ
extconf.rb ã®ã以äžã®ããã«æžãïŒãã® extconf.rb ã®äžèº«ã¯åç¯ã®å 容ããã®å€æŽã¯ãªãïŒ greeter ãšããååã§æ¡åŒµã©ã€ãã©ãªãäœãããã® Makefile ãäœæããããã«æç€ºããŠããïŒ
require "mkmf"
create_makefile("greeter")
次ã«ïŒMakefileãäœãããã« extconf.rb ãå®è¡ãïŒããã« make ããïŒ
$ ruby extconf.rb
$ make (Windows11 ã®å Žåã¯ïŒridk exec make)
$ ls
Makefile extconf.rb greeter.so hello2.c hello2.o
extconf.rb å ã§ greeter ãäœãããæå®ããŠããã®ã§ make ããçµæãšã㊠greeter.so ãäœæãããïŒ ããã Ruby ããå®è¡ããŠã¿ãïŒmain2.rb ã以äžã®ããã«æžãïŒ
require "./greeter" #greeter.so ã䜿ãããã«
obj = Greeter.new #ã¢ãžã¥ãŒã«çãšç°ãªãïŒæåã«ã€ã³ã¹ã¿ã³ã¹ obj ãäœæ
obj.hello
main2.rb ãå®è¡ããïŒ
$ ruby main2.rb
Hello, world! (<-- ç¡äºã«åºåããã)
æ¡åŒµã©ã€ãã©ãªäœæã®å ·äœäŸ: æ°ã®è¶³ãç®
æ¡åŒµã©ã€ãã©ãªå : ã¢ãžã¥ãŒã«ç
2 ã€ã®æ°ã®è¶³ãç®ãè¡ã C ããã°ã©ã ã Ruby ã®æ¡åŒµã©ã€ãã©ãªåããïŒ
$ mkdir -p ~/ruby-extlib/04
$ cd ~/ruby-extlib/04
ããã§ã¯ïŒC èšèªã§ Calc ãšããåã®ã¢ãžã¥ãŒã«ãå®çŸ©ãïŒ ããã« add ãšããã¡ãœãããå ããããšã«ããïŒ C èšèªã§ã¢ãžã¥ãŒã«ãå®çŸ©ããå Žåã¯ïŒä»¥äžã®ãã㪠ããã°ã©ã (add.c) ãäœæããïŒ
#include "ruby.h" // ruby.h ã®ã€ã³ã¯ã«ãŒãã¯å¿
é
//è¶³ãç®ããã°ã©ã ã®æ¬äœ.
int add(int a, int b){
return( a + b );
}
// ã©ãããŒé¢æ°
// * 颿°ã®åã¯åžžã« VALUE
// * 颿°ã®åŒæ°ã®åã¯åžžã« VALUEïŒç¬¬äžåŒæ°ã®åå㯠self ã«ããŠããããšïŒ
// * ããŒã¿ã®å€æãè¡ãããŠããããšã«æ³šæïŒRuby ã§ã¯æ°å€ãå«ããã¹ãŠã®ãã®ããªããžã§ã¯ããšããŠæ±ãããŠããïŒ
// åã
ã®ãªããžã§ã¯ã㯠C ã®æ§é äœãšããŠå®è£
ãããŠããïŒãã®ããïŒC èšèªã§æžããã©ã€ãã©ãªãšæ°å€ã®
// ãããšããããã«ã¯ïŒæ§é äœããæ°å€ãåãåºãããïŒæ°å€ãæ§é äœã«å
¥ããå¿
èŠãããïŒæŽæ°åãæµ®åå°æ°ç¹åã¯
// ç°¡åã«çžäºå€æãããã¯ãã颿°ãããã®ã§ïŒãããå©çšããïŒ
VALUE wrap_add(VALUE self, VALUE aa, VALUE bb){
int a, b, result;
a = FIX2INT(aa);
b = FIX2INT(bb);
result = add(a,b);
return INT2FIX(result);
}
// ã©ã€ãã©ãªã®åæå颿°
// * Ruby ã¯ã©ã€ãã©ãªãèªã¿èŸŒãã ããŸã ãInit_ã©ã€ãã©ãªåã ãšãã颿°ãå®è¡ããããïŒä»å㯠Init_calc ãšããïŒ
// * 颿°ã®åã¯åžžã« void
// * rb_define_module ã§ã¢ãžã¥ãŒã«åãå®ãã
// * Ruby ã§ã¯ã¢ãžã¥ãŒã«åã®å
é ã¯å€§æåã«ããã®ã§ Calc ãšãã (äžæ¹ã§ïŒãã¡ã€ã«åãªã©ã¯å
šéšå°æåã§è¯ãã)ïŒ
// * rb_define_module_function ã§ã¡ãœããåãšïŒã¡ãœããåã«å¯Ÿå¿ããã©ãããŒé¢æ°åãç»é²ããïŒ
void Init_calc(){
VALUE module = rb_define_module("Calc");
rb_define_module_function(module, "add", wrap_add, 2);
}
ãã® add.c ããã°ã©ã ãã³ã³ãã€ã«ããïŒRuby ã«ã¯æ¡åŒµã©ã€ãã©ãªãã³ã³ãã€ã«ããããã® Makefile ãäœãä»çµã¿ãããã®ã§ïŒãããå©çšããïŒ ãã®ããã«ïŒãŸãïŒå¿ èŠãªãœãŒã¹ã³ãŒãã 1 ã€ã®ãã£ã¬ã¯ããªã«ãŸãšãïŒ åããã£ã¬ã¯ããªã« extconf.rb ãšããååã®ãã¡ã€ã«ãäœãïŒ
require "mkmf"
create_makefile("calc")
ãã® extconf.rb ã§ã¯ Calc ãšããååã§æ¡åŒµã©ã€ãã©ãªãäœãããã® Makefile ãäœæããããã«æç€ºããŠããïŒ æ¬¡ã«ïŒMakefileãäœãããã« extconf.rb ãå®è¡ãïŒããã« make ããïŒextconf.rb å ã§ calc ãäœãããæå®ããŠããã®ã§ïŒmake ããçµæãšã㊠calc.so ãäœæãããïŒ
$ ruby extconf.rb
$ make (Windows11 ã®å Žåã¯ïŒridk exec make)
$ ls
Makefile add.c add.o calc.so extconf.rb
extconf.rb å ã§ calc ãäœãããæå®ããŠããã®ã§ make ããçµæãšã㊠calc.so ãäœæãããïŒ ããã Ruby ããå®è¡ããŠã¿ãïŒmain3.rb ã以äžã®ããã«æžãïŒ
require "./calc" #calc.so ã䜿ãããã«
a = 1
b = 2
sum = Calc.add(a, b)
puts "#{a} + #{b} = #{sum}"
main3.rb ãå®è¡ããïŒ
$ ruby main3.rb
1 + 2 = 3 (<-- ç¡äºã«åºåããã)
æ¡åŒµã©ã€ãã©ãªå : ã¯ã©ã¹ç
2 ã€ã®æ°ã®è¶³ãç®ãè¡ã C ããã°ã©ã ã Ruby ã®æ¡åŒµã©ã€ãã©ãªåããïŒ
$ mkdir -p ~/ruby-extlib/05
$ cd ~/ruby-extlib/05
ããã§ã¯ïŒC èšèªã§ Calc ãšããåã®ã¢ãžã¥ãŒã«ãå®çŸ©ãïŒ ããã« add ãšããã¡ãœãããå ããããšã«ããïŒ C èšèªã§ã¢ãžã¥ãŒã«ãå®çŸ©ããå Žåã¯ïŒä»¥äžã®ãã㪠ããã°ã©ã (add.c) ãäœæããïŒ
#include "ruby.h" // ruby.h ã®ã€ã³ã¯ã«ãŒãã¯å¿
é
// ã©ãããŒé¢æ°
// * 颿°ã®åã¯åžžã« VALUE
// * 颿°ã®åŒæ°ã®åã¯åžžã« VALUEïŒç¬¬äžåŒæ°ã®åå㯠self ã«ããŠããããšïŒ
// * ããŒã¿ã®å€æãè¡ãããŠããããšã«æ³šæïŒRuby ã§ã¯æ°å€ãå«ããã¹ãŠã®ãã®ããªããžã§ã¯ããšããŠæ±ãããŠããïŒ
// åã
ã®ãªããžã§ã¯ã㯠C ã®æ§é äœãšããŠå®è£
ãããŠããïŒãã®ããïŒC èšèªã§æžããã©ã€ãã©ãªãšæ°å€ã®
// ãããšããããã«ã¯ïŒæ§é äœããæ°å€ãåãåºãããïŒæ°å€ãæ§é äœã«å
¥ããå¿
èŠãããïŒæŽæ°åãæµ®åå°æ°ç¹åã¯
// ç°¡åã«çžäºå€æãããã¯ãã颿°ãããã®ã§ïŒãããå©çšããïŒ
VALUE wrap_add(VALUE self, VALUE aa, VALUE bb){
int a, b, result;
a = FIX2INT(aa);
b = FIX2INT(bb);
result = a + b ; //çŽæ¥èšç®
return INT2FIX(result);
}
// ã©ã€ãã©ãªã®åæå颿°
// * Ruby ã¯ã©ã€ãã©ãªãèªã¿èŸŒãã ããŸã ãInit_ã©ã€ãã©ãªåã ãšãã颿°ãå®è¡ããããïŒä»å㯠Init_calc ãšããïŒ
// * 颿°ã®åã¯åžžã« void
// * rb_define_module ã§ã¢ãžã¥ãŒã«åãå®ãã
// * Ruby ã§ã¯ã¢ãžã¥ãŒã«åã®å
é ã¯å€§æåã«ããã®ã§ Calc ãšãã (äžæ¹ã§ïŒãã¡ã€ã«åãªã©ã¯å
šéšå°æåã§è¯ãã)ïŒ
// * rb_define_module_function ã§ã¡ãœããåãšïŒã¡ãœããåã«å¯Ÿå¿ããã©ãããŒé¢æ°åãç»é²ããïŒ
void Init_calc(){
VALUE class = rb_define_class("Calc", rb_cObject);
rb_define_method(class, "add", wrap_add, 2);
}
ãã® add.c ããã°ã©ã ãã³ã³ãã€ã«ããïŒRuby ã«ã¯æ¡åŒµã©ã€ãã©ãªãã³ã³ãã€ã«ããããã® Makefile ãäœãä»çµã¿ãããã®ã§ïŒãããå©çšããïŒ ãã®ããã«ïŒãŸãïŒå¿ èŠãªãœãŒã¹ã³ãŒãã 1 ã€ã®ãã£ã¬ã¯ããªã«ãŸãšãïŒ åããã£ã¬ã¯ããªã« extconf.rb ãšããååã®ãã¡ã€ã«ãäœãïŒ
require "mkmf"
create_makefile("calc")
ãã® extconf.rb ã§ã¯ Calc ãšããååã§æ¡åŒµã©ã€ãã©ãªãäœãããã® Makefile ãäœæããããã«æç€ºããŠããïŒ æ¬¡ã«ïŒMakefileãäœãããã« extconf.rb ãå®è¡ãïŒããã« make ããïŒextconf.rb å ã§ calc ãäœãããæå®ããŠããã®ã§ïŒmake ããçµæãšã㊠calc.so ãäœæãããïŒ
$ ruby extconf.rb
$ make (Windows11 ã®å Žåã¯ïŒridk exec make)
$ ls
Makefile add.c add.o calc.so extconf.rb
extconf.rb å ã§ calc ãäœãããæå®ããŠããã®ã§ make ããçµæãšã㊠calc.so ãäœæãããïŒ ããã Ruby ããå®è¡ããŠã¿ãïŒmain4.rb ã以äžã®ããã«æžãïŒãŸãïŒã¢ãžã¥ãŒã«çãšç°ãªãïŒæåã«ã€ã³ã¹ã¿ã³ã¹ obj ãäœæããŠããïŒ
require "./calc" #calc.so ã䜿ãããã«
a = 1
b = 2
obj = Calc.new
sum = obj.add(a, b)
puts "#{a} + #{b} = #{sum}"
main4.rb ãå®è¡ããïŒ
$ ruby main4.rb
1 + 2 = 3 (<-- ç¡äºã«åºåããã)