mieki256's diary



2022/08/16(火) [n年前の日記]

#1 [ruby] Ruby + ffi の動作確認をした

Windows10 x64 21H2上で、Ruby + ffi の動作確認をしてみた。ffi というのは、Ruby から .dll や .so の中にある関数を呼び出せるようになる外部ライブラリ。という説明で合ってるのかどうか…。

_ffi | RubyGems.org
_ffiの全バージョン履歴 | RubyGems.org

動作確認に使ったソース。 :

以下で紹介されていたソースを使わせてもらって動作確認した。user32.dll と MessageBoxA() を使って、メッセージボックスを表示するだけのスクリプト。

_winapi - What are the Ruby Win32API Parameters | How do I pass a null pointer? - Stack Overflow

_02_messagebox_ffi.rb
require "rubygems"
require 'ffi'

module Win32
  extend FFI::Library
  ffi_lib "user32"
  attach_function :messageBox, :MessageBoxA, [:pointer, :string, :string, :long], :int
end

rc = Win32.messageBox(nil, "Hello World", "MessageBoxA by FFI", 0x40)
puts rc

動作確認環境とインストール手順。 :

Ruby 2.6.10 p210 i386-mingw32 の場合。
gem install ffi
ffi 1.15.5 x86-mingw32 がインストールされた。動作した。

Ruby 1.9.3 p551 i386-mingw32 の場合。
gem install ffi -v 1.9.14
Ruby 1.8/1.9 に対応している ffi の最終版は 1.9.14 らしい。-v 1.9.14 でバージョンを指定してインストール。x86-mingw32版がインストールされた。動作した。

Ruby 1.8.7 p330 i386-mswin32、Ruby 1.8.7 p330 i386-mingw32 の場合。
gem install ffi -v 1.9.14 --platform x86-mingw32
動作した。ただ、注意点がある。require "ffi" をする前に、require "rubygems" を記述すること。

Ruby 1.8 までは require "rubygems" を記述しないと、rubygems でインストールしたライブラリを理由できなかったけれど。 Ruby 1.9 以降は require "rubygems" を記述しなくても動くことを忘れていて、「動かない」「動かない」と何時間も悩んでしまった…。

試行錯誤の記録。 :

Ruby 1.8.7 p330 i386-mswin32 に以下でインストールしてみたが、これは動かなかった。
gem install ffi -v 1.9.14 --platform x86-mingw32
02_messagebox_ffi.rb:12:in `require': no such file to load -- ffi (LoadError)
        from 02_messagebox_ffi.rb:12

ビルドしないとダメなのかと、RubyInstaller版の Ruby 1.8.7 p330 i386-mingw32 + DevKit をインストールして、以下を打ったらビルドが通ったが、しかしこれも動かない。
gem install ffi -v 1.9.14 --platform ruby

動作していたらしきバージョンをググって探した。

_Windows XPにwatir-webdriverをインストールする | メモログ

1.0.9 なら動いていたらしい…?
gem install ffi -v 1.0.9
動かなかった。

_Version 1.0.7 doesn't work with ruby versions > 1.8.7 - Issue #341 - ffi/ffi

1.0.7 も動かないと言われてるな…。

ふと、突然思い出した。Ruby 1.8 時代は、rubygems でインストールしたライブラリを使う場合、何かおまじないが必要だった気がする。

ググってみた。require "rubygems" を最初に書いておかないとダメだったのでは。

require "ffi" の前に追加。
require "rubygems"
require "ffi"

あっさり動いた…。
Ruby 1.8.7 p330 mingw32 + ffi 1.9.14 x86-mingw32 も動いた。
Ruby 1.8.7 p330 mswin32 + ffi 1.9.14 x86-mingw32 も動いた。

そういうオチか…。トホホ。

余談。win32apiバージョン。 :

Windows10 x64 21H2 + Ruby 1.8.7 p330 mswin32版上で、win32api を使ってメッセージボックスを表示する例も試してみた。

_01_messagebox_win32api.rb
require "Win32API"

msgbox = Win32API.new('user32', 'MessageBoxA', %w(p p p i), 'i')
msgbox.call(0, "Hello World.", "MessageBoxA", 0x40)

これも動作してくれた。

以上です。

過去ログ表示

Prev - 2022/08 - Next
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31

カテゴリで表示

検索機能は Namazu for hns で提供されています。(詳細指定/ヘルプ


注意: 現在使用の日記自動生成システムは Version 2.19.6 です。
公開されている日記自動生成システムは Version 2.19.5 です。

Powered by hns-2.19.6, HyperNikkiSystem Project