Linuxマシンから別のWindowsマシン上のdllを使う
市販のCCDカメラや望遠鏡などの制御ソフトはどうしてもWindows用に作られていることが多く、Linuxからそれらのハードウェアを使いたい時にはLinux用ドライバーが存在しない場合に困ることがある。 しかし、以下の方法を使えば、LinuxからWindowsのAPIやDLLを使うことができる。
(1)まず、Windows上のRubyでWindowsソフトを利用する。その方法は、筆者が勉強したところでは、2つある。
a)RubyのライブラリRuby/DLを使えば、同一マシン上ののWindowsのAPIやDLLをRubyで書いたソフトから利用できる
b)RubyのライブラリRuby/Win32OLEを使えば、同一マシン上のWinowdsソフトのOLE・COMを利用できる。
(2)そのソフトを分散ruby(dRuby)を使ってサーバソフトとして書ける。そうすれば、ネット上の別のマシンに(あるいは同一マシン上のバーチャルマシンに)サービスを提供できる。
(3)ネット上にあるLinuxマシン(あるいは同一マシン上のバーチャルLinuxマシン)のruby(dRuby)でクライアントソフトを書けば、ネット上のWindowsマシンにつながったハードウェアをリモートで制御できるようになる。
(1)Windows上のRubyでWindowsソフトを利用する。
(a)RubyのライブラリRuby/DLで、WindowsのAPIやDLLを利用する方法
速さが必要な処理でもそれはDLLに任せて、Rubyでインターフェース部を書ける。
参考リンク
Ruby/DLでWin32 APIのMessageBoxを呼んでみた
(b)Rubyでは、WindowsアプリのCOMオブジェクトを使うライブラリWIN32OLEが利用できるので、これを使う方法
以下はその例。
(2)そのソフトを分散ruby(dRuby)を使ってサーバソフトとして書く
druby作者による解説サイト
druby作者による「dRubyによる分散・Webプログラミング 」(単行本)
例 分散Rubyによるサーバソフトの例(冷却CCDを制御するWindowsマシンに置く)
require 'drb' #dRubyライブラリを読み込む require 'win32ole' class WIN32OLE @const_defined = Hash.new def WIN32OLE.new_with_const(prog_id, const_name_space) result = WIN32OLE.new(prog_id) unless @const_defined[const_name_space] then WIN32OLE.const_load(result, const_name_space) @const_defined[const_name_space] = true end return result end end module CCDSoft #CCDSoftのCOMを利用する def CCDSoft.new() ccdsoft = WIN32OLE.new_with_const('CCDSoft.Camera', CCDSoft) return ccdsoft end def CCDSoft.runDuring(&block) begin ccdsoft = new() block.call(ccdsoft) ensure ccdsoft.quit end end end DRb.start_service('druby://:12345', CCDSoft.new) #「12345」はポート番号で任意の指定ができる puts DRb.uri sleep #この3行でdRubyを使ったサーバになる
(3)dRubyで書いたクライアントソフトからdRubyを使ったサーバを利用する(linuxマシンに置くソフト)
#! /usr/bin/ruby1.8 # Ver.0.20 2010.12.18 add CCD status from CCDSoft of Windows machine require 'drb' require "dispConsole.rb" require "DACS1500.rb" #望遠鏡を制御するクラス include Disp dt=DRbObject.new_with_uri('druby://localhost:12345') @ccdt=DRbObject.new_with_uri('druby://winndy:12345') #CCDstat serverに接続 def ccd_exp #サーバからCCDの露出ステータスを得るメソッド str=@ccdt.status end def ccd_temp #サーバからCCDの温度を得るメソッド str=@ccdt.temperature sprintf("%.3g",str) end def temp_power #サーバからCCDの冷却パワー情報を得るメソッド str=@ccdt.thermalelectriccoolerpower sprintf("%.2g",str) end c = Controll_Terminal.new dacs15k=DACS1500.new loop do begin dt.renew ha=dt.ha.to_f $ha=Angle.new(ha) hour=Time.new.hour if (hour>5)and(hour<17) then dacs15k.stopSiderealTracking c.disp(22,10, "Siderial clock was stopped!! ") end lst=Angle.new(dt.lst).to_hms rA=Angle.new(dt.ra) dEc=Angle.new(dt.dec) c.disp(3,3,"Date: "<<dt.date_t) c.disp(3,48,"JD:"<<dt.jd.to_s) (中略) c.disp(15,17, ccd_exp) c.disp(16,17, ccd_temp<<"deg("<<temp_power<<"%)") rescue => ex c.disp(15,17, "Telescope Error !!") ex.message end sleep(0.8) end
技術的な覚書きへ戻る
8481
Keyword(s):[Ruby/DL] [dRuby] [Windows共有ライブラリをLinuxから使う]
References:[技術的な覚書き]