Hatena::ブログ(Diary)

hogeなlog

プロフィール

hogelog

hogelog

小室 直(こむろ すなお)。電気通信大学2003年入学。2010年修士卒業。プログラミングとかしてます。

カレンダー
1984 | 01 |
2006 | 07 | 08 | 09 | 10 | 11 | 12 |
2007 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2008 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2009 | 01 | 02 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 |
2010 | 01 | 06 | 08 | 09 | 10 | 11 | 12 |
2011 | 01 | 02 | 03 | 05 | 08 | 09 | 10 | 12 |
2012 | 01 | 04 | 06 |

June 26(Thu), 2008

[][] ruby拡張を書いてみるテスツ

すごく簡単だった。rubyアーカイブに同梱されてるREADME.EXTすら読まずに適当に雰囲気で作れた。というわけで合ってないかもしれないけど。画面サイズとDPIを取得するモジュール。

require 'sinfo'

printf "%dx%d (px)\n", ScreenInfo::W_PX, ScreenInfo::H_PX
printf "%dx%d (mm)\n", ScreenInfo::W_MM, ScreenInfo::H_MM
printf "%dx%d (dpi)\n", ScreenInfo::W_DPI, ScreenInfo::H_DPI

こんなコードが

1024x768 (px)
271x203 (mm)
9640x9650 (dpi)

こんな出力をするもの。sinfoをrequireしたときの画面情報取得してモジュールScreenInfoの定数にぶちこむだけ。


ソースコードsinfo.cはこんなの。requireしたときの初期化動作を記述したInit_sinfo書いてるだけ。

#include "ruby.h"
#ifdef WIN32
#include <windows.h>
#else
#include <X11/Xlib.h>
#endif

static VALUE mSInfo;
void Init_sinfo(void) {
  mSInfo = rb_define_module("ScreenInfo");
  int w_px, w_mm, w_dpi;
  int h_px, h_mm, h_dpi;
#if defined(WIN32)
  HDC dc;
  dc = GetDC(GetDesktopWindow());
  if(dc == NULL) {
    rb_raise(rb_eLoadError, "sinfo: fail to GetDesctopWindow");
    return;
  }
  w_px = GetDeviceCaps(dc, HORZRES);
  w_mm = GetDeviceCaps(dc, HORZSIZE);
  h_px = GetDeviceCaps(dc, VERTRES);
  h_mm = GetDeviceCaps(dc, VERTSIZE);
  ReleaseDC(GetDesktopWindow(), dc);
#elif defined(_XLIB_H_)
  Display *display = XOpenDisplay(NULL);
  if(display == NULL) {
    rb_raise(rb_eLoadError, "sinfo: fail to XOpenDisplay");
    return;
  }
  w_px = DisplayWidth(display, DefaultScreen(display));
  w_mm = DisplayWidthMM(display, DefaultScreen(display));
  h_px = DisplayHeight(display, DefaultScreen(display));
  h_mm = DisplayHeightMM(display, DefaultScreen(display));
  XCloseDisplay(display);
#endif
  w_dpi = (w_px*254 + w_mm*5) / w_mm*10;
  h_dpi = (h_px*254 + h_mm*5) / h_mm*10;
  rb_define_const(mSInfo, "W_PX", INT2FIX(w_px));
  rb_define_const(mSInfo, "W_MM", INT2FIX(w_mm));
  rb_define_const(mSInfo, "H_PX", INT2FIX(h_px));
  rb_define_const(mSInfo, "H_MM", INT2FIX(h_mm));
  rb_define_const(mSInfo, "W_DPI", INT2FIX(w_dpi));
  rb_define_const(mSInfo, "H_DPI", INT2FIX(h_dpi));
}

そして以下のようなrubyスクリプトextconf.rbとを作る。

#!/usr/bin/ruby

require 'mkmf'
create_makefile 'sinfo'

あとは

$ ruby extconf.rb
$ make
# make site-install

でおしまい。処理系の拡張機能とかは他にはPHPしか作ったことないから比較対象多くないけど、これはすごく作りやすくていいなあと思う。書き易さもそうだけど読みやすさもこっちのが格段上。言語は同じCなんだけどねえ。俺にとってはこれだけで十分好きになる理由になるなあと感じた。

最近のコメント