2010年6月29日火曜日

IronRubyでSystem::IO::Ports::SerialPort

のサンプル 3をironrubyでやってみました。
SD-RDの接続でのLOOPです。
SharpDevelop3.2(IronRuby 1.0.0.0 on .NET 2.0.50727.3063)デバックでは
System.InvalidOperationException: 有効ではないスレッド間の操作: コントロールが作成されたスレッド以外のスレッドからコントロール 'textBox1' がアクセスされました。
が出て、だめでした。

IronRuby 1.0.0.0 on .NET 4.0.30319.1にて
>ir -Ku  sio_cs3_utf8.rbで実行して表示できました。



#sio_cs3_utf8.rb

#require "System"
#require 'System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'
require "mscorlib"
#require "System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
#require "System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
require "System.Windows.Forms"
require "System.Drawing"

class MainForm <>
def initialize()
self.InitializeComponent()
# C#: private byte[] readBuffer = new byte[1024];
# @readBuffer = Array.CreateInstance(System::Byte, 1024)
@readBuffer = System::Array[System::Byte].new(1024)
@readBufferLength = 0
@serialPort1.Open()
end

def InitializeComponent()
@components = System::ComponentModel::Container.new()
@button1 = System::Windows::Forms::Button.new()
@textBox1 = System::Windows::Forms::TextBox.new()
@textBox2 = System::Windows::Forms::TextBox.new()
@serialPort1 = System::IO::Ports::SerialPort.new(@components)
self.SuspendLayout()
#
# button1
#
@button1.Location = System::Drawing::Point.new(205, 231)
@button1.Name = "button1"
@button1.Size = System::Drawing::Size.new(87, 23)
@button1.TabIndex = 0
@button1.Text = "送信"
@button1.UseVisualStyleBackColor = true
@button1.Click { |sender, e| self.btn_send_click(sender, e) }
#
# textBox1
#
@textBox1.Location = System::Drawing::Point.new(0, 1)
@textBox1.Multiline = true
@textBox1.Name = "textBox1"
@textBox1.ScrollBars = System::Windows::Forms::ScrollBars.Vertical
@textBox1.Size = System::Drawing::Size.new(292, 224)
@textBox1.TabIndex = 1
#
# textBox2
#
@textBox2.Location = System::Drawing::Point.new(0, 231)
@textBox2.Name = "textBox2"
@textBox2.Size = System::Drawing::Size.new(199, 19)
@textBox2.TabIndex = 2
#
# serialPort1
#
@serialPort1.DtrEnable = true
@serialPort1.RtsEnable = true
@serialPort1.DataReceived { |sender, e| self.serialport_datarecived(sender, e) }
#
# MainForm
#
self.ClientSize = System::Drawing::Size.new(295, 266)
self.Controls.Add(@textBox2)
self.Controls.Add(@textBox1)
self.Controls.Add(@button1)
self.Name = "MainForm"
self.Text = "シリアルポートチャットサンプル"
self.FormClosed { |sender, e| self.Form_Closed(sender, e) }
self.ResumeLayout(false)
self.PerformLayout()
end

def btn_send_click(sender, e)
mes = @textBox2.Text.Trim
if mes == "" then
return
end
buf = System::Text::Encoding.GetEncoding("Shift_JIS").GetBytes(mes)
size = buf.Length
@serialPort1.Write(System::BitConverter.GetBytes(size), 0, 2) #sizeof(short) = 2
@serialPort1.Write(buf, 0, size)
@textBox1.AppendText("自分: " + mes + "\r\n")
@textBox2.Text = ""
end

def serialport_datarecived(sender, e)
len = @serialPort1.Read(@readBuffer, @readBufferLength, @readBuffer.Length - @readBufferLength)
if len == 0 then
return
end
@readBufferLength += len
if @readBufferLength <>
# まだ先頭のデータサイズ部分を読み込めていない
return
end
while true
size = System::BitConverter.ToInt16(@readBuffer, 0) #先頭に格納されている送信text size
if @readBufferLength <>
# データサイズ部分は読み込んでいるがデータ部分の一部しか読み込んでいない
# if @readBuffer.Length <>
# # バッファサイズが足らないので広げる
# buf = System::Array[System::Byte].new (size + 2)
# System::Array.Copy(@readBuffer, buf, @readBuffer.Length)
# @readBuffer = buf
# end
return
end
mes = System::Text::Encoding.GetEncoding("Shift_JIS").GetString(@readBuffer, 2, size)
System::Array.Copy(@readBuffer, 2 + size, @readBuffer, 0, @readBufferLength - 2 - size)
@readBufferLength -= (2 + size)
# C#:this.BeginInvoke(new AppendMessageDelegate(AppendMessage), new object[] { mes });
#self.BeginInvoke(AppendMessageDelegate.new(AppendMessage), Array[System::Object].new([mes]))
BeginInvoke(self.AppendMessage(mes))
end
end
def AppendMessage(mes)
@textBox1.AppendText("相手: " + mes + "\r\n")
end

def Form_Closed(sender, e)
@serialPort1.Close()
@serialPort1.Dispose()
end
end

Application = System::Windows::Forms::Application

Application.EnableVisualStyles()
form = MainForm.new()
Application.Run(form)




0 件のコメント:

コメントを投稿