2013-12-04

「指定されたプロシージャが見つかりません。」の調べ方(Dependency Walker編)

GNOME Advent Calendar 2013 の4日目の記事です。

今回は、WindowsでGNOMEライブラリーを使おうとしたときに、

「127: 指定されたプロシージャが見つかりません。」

というエラーが発生したときの調査方法を紹介します。このエラーだけだと
何が悪いのか全くわからないので、もう少し情報を得る必要があります。

GNOMEライブラリーはC言語で書かれているので、実行時にはコンパイルと
リンクがされた状態になっています。このままではエラーの原因を見つけるのは
難しいので、内容を見やすい形で出力します。そのためのツールはいくつか
ありますが、ここではGUIツールの「Dependency Walker」を使います。

Dependency Walker (depends.exe) Home Page

Dependency Walkerは、Windows用のモジュール(.exeや.dllなど)を解析して、
含まれているモジュールや関数をツリー化して見やすく表示してくれます。

使い方の大まかな流れは、

  1. 調査するモジュールを開く
  2. 依存するモジュールのパスを登録する
  3. 足りないモジュールや関数を探す

という感じです。

それでは、具体的に見ていきます。

1. 調査するモジュールを開く

メニューバー > File か、ドラッグ&ドロップで簡単に開けます。
ここで黄色い「?」マークが表示された場合、依存するモジュールのパスが
登録されていない可能性が高いです。

2. 依存するモジュールのパスを登録する

単体で動作するモジュールなら、単純に開けばよいのですが、
他のモジュールに依存している場合、パスを登録する必要があります。
まず、メニューバー > Options > Configure Module Search Order...
で設定ウィンドウを開きます。

追加方法は、1つずつ追加する方法と、ファイルから読み込む方法があります。

1つずつ追加する場合、下のテキストボックスにパスを設定して、
左下の「Add Directory」ボタンを押します。

ファイルから読み込む場合、右側の「Load」ボタンからファイルを選択します。
一度「Save」で出力してみると、どんな風に書くかわかります。

例えば、Ruby-GNOME2プロジェクトのPangoライブラリーのpango.soの
依存関係を調査したい場合、以下のようなファイルを読み込むとよいです。

PangoはGLibとcairoを使っているので、それらのDLLファイルなどが含まれた
ディレクトリを指定します。

最後に「OK」ボタンを押せば、一覧が更新されるはずです。

3. 足りないモジュールや関数を探す

黄色い「?」マークがなくなったら準備完了なので、調査を開始します。

探し方は、まず左上のツリーで赤くなっているモジュールを探します。
それをクリックすると、右上に含まれている関数が表示されるので、
その中のどの関数に問題があるか(赤くなっているか)を調べます。

ここまで調べられれば、モジュールの開発者に報告するなり、
Googleで関数名を検索するなりして対応できそうな気がします。

(もし「?」マークがなくならなかったら、そのモジュールが足りないということです。)

まとめ

Dependency Walkerというツールを使って、コンパイル&リンク済みの
Windows用モジュールの問題を調査する方法を説明しました。

ログが何も出ないエラーが発生すると途方に暮れてしまいがちですが、
少しでも手がかりが見つかると楽しくなってくる(場合もある)ので、
ぜひ挑戦してみてください。

2013-12-03

GtkAdventCalendarで作るアドベントカレンダーアプリ

GNOME Advent Calendar 2013 の3日目の記事です。 2日目はクリアコードさんのGTK-Docの使い方 でした。

今回は、 1日目 に作成した GtkAdventCalendar をライブラリーとして使い、
カスタマイズしたアドベントカレンダーアプリを作成します。
(今回は、前回に増してRubyの話がほとんどで、GNOMEっぽくないです)

まずは、GtkAdventCalendarをライブラリーとして使いやすいように修正します。

修正点

  1. 日付ボタンをクリックしたときの動作を変更しやすくする
    • メソッドに切り出す
  2. requireで読み込みやすくする

具体的には以下の通りです。

1. 日付ボタンをクリックしたときの動作を変更しやすくする

lib/gtk_advent_calendar/calendar.rb

修正前

module GtkAdventCalendar
  class Calendar
    ...
    def day(n)
      ...
      button.signal_connect("clicked") do
        show_uri("http://en.wikipedia.org/wiki/December_#{n}")
      end
      ...
    end
    ...
  end
end

修正後

module GtkAdventCalendar
  class Calendar
    ...
    def day(n)
      ...
      button.signal_connect("clicked") do
        action(n)
      end
      ...
    end

    def action(n)
      show_uri("http://en.wikipedia.org/wiki/December_#{n}")
    end
    ...
  end
end

これで、action(n)メソッドを上書きするだけで、日付のボタンを
押したときの動作を変更することができるようになりました。

2. requireで読み込みやすくする

Rubyでは、ライブラリーは主にrequireコマンドで読み込みますが、
ファイル名まで指定するのは面倒です。(前回の Commandクラス を参照)

そこで、ライブラリー名だけでCalendarクラスを読み込めるようにします。

lib/gtk_advent_calendar.rb

修正前

require "gtk_advent_calendar/version"

ここにパスを書いておくと、require "gtk_advent_calendar"で読み込まれます。

versionを読み込んでいる行は、bundle gemコマンドでRubyGems用の
雛形を作成したときに生成されたものです。そこにcalendarも追加します。

修正後

require "gtk_advent_calendar/version"
require "gtk_advent_calendar/calendar"

これで、require "gtk_advent_calendar"と書くだけで
GtkAdventCalendar::Calendarクラスが使えるようになりました。

参考までに、RubyGemsの雛形については @hibariya さんのスライドに
わかりやすくまとまっています。興味のある方はぜひご覧ください。
https://speakerdeck.com/hibariya/code

インストール

ライブラリーとして使う場合も、前回と同様にgemコマンドでインストールします。

% gem install gtk_advent_calendar

README に記載されている通り、Gemfile等に記述してもOKです。

サンプルコード

以下のように使います。

sample/your_calendar.rb

#!/usr/bin/env ruby

require "gtk_advent_calendar"

class YourCalendar < GtkAdventCalendar::Calendar
  # @params n [Integer] the day between 1 and 25.
  def action(n)
    puts "It's December #{n}."
  end
end

window = Gtk::Window.new
window.add(YourCalendar.new)
window.signal_connect("destroy") do
  Gtk.main_quit
end
window.show_all
Gtk.main

元々はWebページが開かれていましたが、標準出力に日付を表示するようにしています。
show_uriメソッドは使えるので、別のWebページを開くようにすることもできます。

  def action(n)
    show_uri("http://hoge.fuga/piyo/#{n}")
  end

まとめ

GtkAdventCalendar gem使って、カスタマイズしたアドベントカレンダーアプリを作成しました。

アプリケーションを作成したら、ライブラリーとしても使いやすくすると
使われる機会が増えるかもしれません。(WebページとAPIの関係に似ていますね)
(ライブラリー部分を別のgemに切り出す方が普通かもしれません)

2013-12-02

Tomster氏の5つの魅力

この記事は Ember.js Advent Calendar の2日目です。

1日目はtricknotesさんの Ember.js はレガシー IE でも動くようになっています、を対応しましたという話 でした。

僭越ながら、 Ember.js のマスコットキャラクターである
Tomster氏の魅力について考察させていただきたいと思います。

1. 名前の語呂がいい

とても語感がよく、呼びやすい名前です。名前重要。
5拍なのも、日本人にとっては俳句や短歌で馴染みが深くてポイント高いです。

2. 名前を略しやすい

英語圏では、会話やメールに本名を使う人はむしろ少なく、
呼びやすい略称などを使う人が多いです。彼もまた、

Tom

という最高に呼びやすい略称を使える可能性を秘めています。
うらやましいですね。

3. 名前の誤読が少ない

どう考えても「とむすたー」以外の読み方が思いつきません。
名前の誤読を訂正するのはとても気まずいことなので、
それをしなくていいというのはかなりのアドバンテージです。

4. 欠番

ここ日本では、「4」という数字はあまり縁起がよくないので、飛ばします。
ちなみに、 Tomster は種族名だという説がありますが定かではありません。

5. 名前にスター性がある

名前に「スター」が入っています。 Tomstar でないのが残念ですが…。

まとめ

Tomster という名前について考察しました。
結論としては、とても良く考えられた名前だと思います。変に凝った名前にしなかった
名付け親の方に敬意を表し、本稿を終えさせていただきます。ありがとうございました。

\Enjoy!/
Tomster

3日目はursmさんの Ember.js と Rails です!

2013-12-01

Ruby/GTK3で作るカレンダーアプリ

GNOME Advent Calendar 2013 1日目の記事です。

Ruby/GTK3を使って、Advent Calendarっぽいアプリを作成します。

機能

  • GUIウィンドウを持つ
  • 1日〜25日までのボタンを付ける
  • 日付のボタンをクリックすると、何かが開く
    • とりあえずWebページ(Wikipedia)にしておく

インストール

RubyGems.orgに公開したので、以下のコマンドでインストールできます。

% gem install gtk_advent_calendar

もしインストールできなかったら、 issuesTwitter でメンションをいただけるとうれしいです。

起動

コマンドラインから起動できます。

% gtk_advent_calendar

ソースコード

ソースコードはGitHubに公開してあります。
https://github.com/myokoym/gtk_advent_calendar

簡単に解説します。

実行ファイル

コマンドラインから実行するためのファイルです。

https://github.com/myokoym/gtk_advent_calendar/blob/master/bin/gtk_advent_calendar

#!/usr/bin/env ruby

require "gtk_advent_calendar/command"

GtkAdventCalendar::Command.run

実行ファイルなので、shebangを付けています。
あとは、Commandクラスのrunメソッドを呼び出しているだけです。

GUIウィンドウ・メインループ

CommandクラスでGUIウィンドウを作成しています。

https://github.com/myokoym/gtk_advent_calendar/blob/master/lib/gtk_advent_calendar/command.rb

require "gtk3"
require "gtk_advent_calendar/calendar"

module GtkAdventCalendar
  class Command
    class << self
      def run
        window = Gtk::Window.new
        window.title = "Advent Calendar"
        window.add(Calendar.new)
        window.signal_connect("destroy") do
          Gtk.main_quit
        end
        window.show_all
        Gtk.main
      end
    end
  end
end

主役はwindow.add(Calendar.new)のCalendarクラスです。
Gtk.mainでGUIアプリケーションのメインループに入ります。

Calendarクラス

ここでカレンダー本体を作ります。

GTKにはいろいろなウィジェットがありますが、
ここでは基本的なウィジェットであるBoxを多用します。

https://github.com/myokoym/gtk_advent_calendar/blob/master/lib/gtk_advent_calendar/calendar.rb

require "gtk3"

module GtkAdventCalendar
  class Calendar < Gtk::Frame
    LAST_DAY = 25
    CELL_WIDTH = 40

    def initialize
      super
      @day = 1
      add(month)
    end

    def month
      box = Gtk::Box.new(:vertical)
      box.add(days_of_the_week)
      while @day <= LAST_DAY do
        box.add(week)
      end
      box
    end

    def days_of_the_week
      box = Gtk::Box.new(:horizontal)
      %w(Sun Mon Tue Wed Thu Fri Sat).each do |day_of_the_week|
        label = Gtk::Label.new("#{day_of_the_week}.")
        label.width_request = CELL_WIDTH
        box.add(label)
      end
      box
    end

    def week
      box = Gtk::Box.new(:horizontal)
      7.times do
        break if @day > LAST_DAY
        box.add(day(@day))
        @day += 1
      end
      box
    end

    def day(n)
      button = Gtk::Button.new(:label => n.to_s)
      button.width_request = CELL_WIDTH
      button.height_request = CELL_WIDTH
      button.signal_connect("clicked") do
        show_uri("http://en.wikipedia.org/wiki/December_#{n}")
      end
      button
    end

    def show_uri(uri)
      case RUBY_PLATFORM
      when /darwin/
        system("open", uri)
      when /mswin|mingw|cygwin|bccwin/
        system("start", uri)
      else
        if Gtk.respond_to?(:show_uri)
          Gtk.show_uri(uri)
        else
          system("firefox", uri)
        end
      end
    end
  end
end

詳しい解説は省略するので、何かあればコメントか Twitter でメンションをください。

まとめ

Ruby/GTK3を使ってカレンダーアプリを作成しました。
これを応用すれば、ランチャーアプリなども簡単に作れると思います。

もしRuby/GTK3に興味を持たれた方がいれば、
プロジェクトページメーリングリスト も参照してみてください。

2日目はクリアコードさんの GTK-Docの使い方 です!

2013-10-30

Ruby/C++用ゲーム開発ライブラリGosuのRubyチュートリアルを日本語訳しました

Gosuとは、RubyとC++に対応した2Dゲーム開発ライブラリです。
ruby-gnome2-devel-enというMLに使っている人がいて存在を知りました。

http://www.libgosu.org/

インストール方法はWikiのサイドバーのGetting Startedです。

https://github.com/jlnr/gosu/wiki

Rubyに対応したゲーム開発ライブラリの中では最有力だと思っています。

  • メンテナンスされている
    • コピーライトは2001-2013
    • 作者の方にメールしたら4時間で返事が来た
  • オープンソース
    • GitHubにホスティング
    • MITライセンス
  • マルチプラットフォーム
    • Mac OS X
    • Windows(Ruby2.0未対応)
    • Linux
    • 参考:C++版はiOSにも対応

とてもよさげなのですが、なぜか日本語の情報がほとんどなかったので、
きちんと理解するためにチュートリアルを日本語に訳してみました。

https://gist.github.com/myokoym/7148859#file-gosu-ruby-tutorial-japanese-md

基本はわかってきたので、あとは実際にアプリケーションを開発しながら
都度アウトプットなりコントリビュートなりしていきたいと思っています。