SerialPortの謎

「なのぼーど」をつなげたPC上で、Fluoのプログラミングを行っているのだが、例によってSerialPortで悩まされている。
ずっとMac OS X上で開発していて特にトラブルがなかったので見過ごしていたが、Windowsで利用すると問題が生じることに気づいた。

現象としては一度オープンしたポートをクローズすると再オープンできなくなるということ。
コードで示すと、2番目のopenPort:でエラーになる。

s := SerialPort new openPort: 'COM3'.
s close.
s openPort: 'COM3'.

これについては既に議論がなされていた。
http://forum.world.st/Package-for-manage-USB-RS232-td4744124.html

SerialPortのソースを眺めてみると、primitiveClosePortByName:に問題があるようだ。

primClosePortByName: portName
	
	^ nil"(DNS)"
	"self primitiveFailed."

わざわざself primitiveFailedがコメントアウトされているのは、コードを書いた人がこの問題を認識していて放置したってことか。
SerialPortではあたかもcloseが成功したかのように見せかけているのだが、実際にはこのプリミティブを呼んだ後、primOpenPortByName:を呼ぶと失敗し、SerialPort>>#openPort:の中でエラーと判定される。

先ほどのメーリングリストのやり取りではSerialPort>>#openPort:内のエラー判定部分を削除すれば動くとあり、試してみたらちゃんと2度目もオープンできた。該当箇所はここ。

	"result isNil ifTrue:[ self error:'Cannot open ', portId printString. ]."

このようにコメントアウトしておけば冒頭のトラブルは回避できる。
これでいいのか甚だ疑問であるが。

プラグインに問題ありそうだから暇を見つけて原因究明してみよう。
とかいってプラグイン関係はいつも挫折してるけど。

(ここから追記)

プラグインのソースを眺めて見ると、プラグインの方でハンドルの管理を行っていた。ポートを名前でなく番号でも呼べるようになっていたのはそのせいか。
WindowsではCOM3に対応する番号は3なので、以下のコードを試してみたらオープンもクローズも問題なく動くではないか。

s := SerialPort new.
s openPort: 3.
s primClosePort: 3.
s openPort: 3.
s primClosePort: 3.

ということでWindows上では番号でポートを指定すれば大丈夫なようだ。