Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
C++言語で簡単なRuby拡張ライブラリを書いてみた

この拡張ライブラリの使用手順

  • このサンプルをダウンロードして解凍したディレクトリで以下を実行
 $ ruby extconf.rb
 $ make
 $ ruby test.rb

ファイルについて

  • extconf.rb
  • 拡張ライブラリのMakefile作成用
  • hello.cpp
  • Helloクラスのコード
  • hello.h
  • Helloクラスのヘッダ
  • hello_wrp.cpp
  • HelloクラスをRubyで利用するためのラッパ
  • test.rb
  • 拡張ライブラリを使用するサンプルスクリプト

試してみた環境

  • OSX 10.7.5
  • ruby 1.9.3p0 (2011-10-30 revision 33570) [x86_64-darwin11.2.0]
  • その他Centos6でも動作を確認

参照サイト

require 'mkmf'
have_library("stdc++")
create_makefile("hello")
#include "hello.h"
#include <stdio.h>
Hello::Hello()
{
}
Hello::~Hello()
{
}
void Hello::sayHello()
{
printf("hello\n");
}
#ifndef __HELLO_H_
#define __HELLO_H_
class Hello
{
public:
Hello();
virtual ~Hello();
void sayHello();
};
#endif
#include <new>
#include <ruby.h>
#include "hello.h"
static Hello* getHello(VALUE self)
{
Hello* p;
Data_Get_Struct(self, Hello, p);
return p;
}
static void wrap_Hello_free(Hello* p)
{
p->~Hello();
ruby_xfree(p);
}
static VALUE wrap_Hello_alloc(VALUE klass)
{
void* p = ruby_xmalloc(sizeof(Hello));
new (p) Hello(); // replacement newにより初期化しておかないとnewに失敗しとき(引数の数が違うとか)デストラクタ呼び出しで死ぬ
return Data_Wrap_Struct(klass, NULL, wrap_Hello_free, p);
}
static VALUE wrap_Hello_init(VALUE self)
{
Hello* p = getHello(self);
new (p) Hello();
return Qnil;
}
static VALUE wrap_Hello_sayHello(VALUE self)
{
getHello(self)->sayHello();
return Qnil;
}
/**
* require時に呼び出し
*/
extern "C" void Init_hello()
{
VALUE c = rb_define_class("Hello", rb_cObject);
rb_define_alloc_func(c, wrap_Hello_alloc);
rb_define_private_method(c, "initialize", RUBY_METHOD_FUNC(wrap_Hello_init), 0);
rb_define_method(c, "say_hello", RUBY_METHOD_FUNC(wrap_Hello_sayHello), 0);
}
require "./hello"
Hello.new.say_hello
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment