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
技術的な覚書きへ戻る
9125
Keyword(s):[Ruby/DL] [dRuby] [Windows共有ライブラリをLinuxから使う]
References:[技術的な覚書き]