Ruby の Fiddle と C言語による動的リンク入門 (Windows, Linux)


C言語で DLL や Shared Object (.so) を作る方法と、それを Ruby から利用する方法のまとめです。

対象環境

OS コンパイラ
Windows Borland C++ Compiler 5.5
Windows Microsoft Visual Studio
Linux GCC

Visual Studio の CL コマンドでコンパイルするには、Visual Studio のインストール時に C++ をインストールしておく必要があります。Visual Studio 2015 ではデフォルトで C++ がインストールされないようです。インストール後にコントロールパネルの [プログラムのアンインストール] のところから Modify を選択してインストールすることもできます。

Visual Studio の CL コマンドでコンパイルする場合は、以下のページを参考に x86 や x64 などのプラットフォームに応じて適切な引数で vcvarsall.bat を実行してからコンパイルを行ってください。

コマンド ライン ビルドのパスと環境変数の設定 | MSDN

目次

DLL, Shared Object の作成

例として、”Hello World!” と表示する show() という関数をC言語で定義し、それをRubyから呼び出すことにします。

  • Borland C++ Compiler の場合

    test.c
    #include <stdio.h>

    __declspec(dllexport) void __stdcall show() {
        printf("Hello World!\n");
    }
    コンパイル方法
    > bcc32 -tWD test.c
  • Microsoft Visual C++ の場合

    test.c
    #include <stdio.h>

    __declspec(dllexport) void show() {
        printf("Hello World!\n");
    }
    コンパイル方法
    > cl /LD test.c

    環境変数が適切に設定されていないとエラーになるので、Visual Studio のコマンドプロンプトで実行すると良いです。

    参考

    コンパイラ オプション一覧

  • GCC の場合

    test.c
    #include <stdio.h>

    void show() {
        printf("Hello World!\n");
    }
    コンパイル方法
    $ gcc -shared -fPIC test.c -o test.so

Ruby から DLL, Shared Object を利用する方法

Ruby の標準添付ライブラリである fiddle を使います。

require "fiddle/import"

module Test
    extend Fiddle::Importer
    dlload __dir__ + '/test.dll'
#   dlload __dir__ + '/test.so'
    extern "void show()"
end

Test.show

Linux の場合、fiddle を使うには Rubyインタプリタをインストールする前に libffi-devel をインストールしておく必要があります。

$ sudo yum install libffi-devel

fiddle がインストールされていない場合、require した時に次のエラーが発生します。

kernel_require.rb:53:in `require’: cannot load such file — fiddle/import (LoadError)

DLL, Shared Object の中身を覗く方法

  • Windows の場合

    Visual Studio に付属の dumpbin コマンドを使います。

    > dumpbin /exports test.dll
  • Linux の場合

    nm や objdump コマンドを使います。

    $ nm -g test.so
    $ objdump -d test.so
カテゴリー: 記事 タグ: , パーマリンク

コメントを残す