VS2005 RS-232C バグの件



これはソフトウェアーの純技術的なことなので
殆どの人はスルーでお願いします。
私のホームページから回って来られた方いらっしゃい。

VB2005でRS-232Cの受信のサンプルコードを書いた。

    C#コード
  private void SerialPort1_DataReceived(object sender,
System.IO.Ports.SerialDataReceivedEventArgs e)
{
//データ受信用のバイト配列
byte[] inByte = new byte[serialPort1.BytesToRead];
//データの読み込み
serialPort1.Read(inByte, 0, serialPort1.BytesToRead);
  VB2005コード
Private Sub SerialPort1_DataReceived(ByVal sender As Object, _
ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) _
Handles SerialPort1.DataReceived
'データ受信用のバイト配列
Dim inByte(SerialPort1.BytesToRead - 1) As Byte
'データの読み込み
SerialPort1.Read(inByte, 0, SerialPort1.BytesToRead)

このたった2行のコードの中にバグが潜んでいた。
さてどこでしょうか?

serialPort1.BytesToReadはバッファの状態を読んでその時の受信データの 長さをByte単位で返すのであるが、実はこのC#とVB2005のコードは この長さを2度読みに行っている。
そしてこれが問題なのだ。
すなわち一度目の配列を確保する為に読みに行った時と、実際に serialPort1.BytesToReadで データを読みに行った時とで返す値が違う可能性があるのだ。

普通のソフトでは考えられないのであるが、RS-232Cの場合は十分考えられる。
次から次にデータが受信されるので配列を確保している間に次のデータを受信して しまうのだ。
そしてあの恐ろしいエラーが出る「配列の長さが範囲を超えている...」と。
これを解決するためには一回だけ読みに行けばよいのである。

書き直されたコード
    C#コード
   int dataLength = serialPort1.BytesToRead;
//データ受信用のバイト配列
byte[] inByte = new byte[dataLength];
//データの読み込み
serialPort1.Read(inByte, 0, dataLength);
  VB2005コード
Dim dataLength as Integer = SerialPort1.BytesToRead
'データ受信用のバイト配列
Dim inByte(dataLength - 1) As Byte
'データの読み込み
SerialPort1.Read(inByte, 0, dataLength)
とすればいいのです。
掲示板に投稿してくれた「たかさん」ごめんなさい。
と言ってもこんな所は読まないか。


同じカテゴリー(PC)の記事画像
Window10アップグレード
PC購入
Windows Update という名の恐怖(2)
Windows Update という名の恐怖(1)
カルチャーショック
USBの不思議
同じカテゴリー(PC)の記事
 Window10アップグレード (2015-09-11 10:50)
 PC購入 (2015-02-23 11:00)
 忙しい (2013-10-01 20:46)
 Windows Update という名の恐怖(2) (2013-07-02 16:19)
 Windows Update という名の恐怖(1) (2013-07-01 11:50)
 カルチャーショック (2012-12-24 08:30)

2010年02月17日 Posted byigoten at 17:42 │Comments(0)PC

 
<ご注意>
書き込まれた内容は公開され、ブログの持ち主だけが削除できます。