Communication Bridgeにバグ発見
研究室にてなんとなしに隣の部屋に行き、RFID班の様子を聞きに行くと、なにやら原因不明なエラーと戦っている模様。どうやらCommunication BridgeでTCP/IP経由を通ってきたパケットが、実際に付属しているサンプルのレスポンスと異なった値が出てくるらしい。2日ぐらい悩んでいたらしいが、Communication Bridge側にバグがあるような気がしたので、ソースを読んでみる事にした。
Communication BridgeはMSComm32のActiveXコンポーネントと通信しているのだが、MSComm32がシリアル通信した結果をVariant型で返す仕様となっている。ちなみに、その部分をCommunication Bridge内ではこのように書いている。
CString strBuffer;
int bufferSize=theApp.m_pmscomm->GetInBufferCount();
COleVariant comInput=theApp.m_pmscomm->GetInput();
CByteArray resvBuffer;
void* pSrc;
resvBuffer.SetSize(bufferSize);
comInput.ChangeType(VT_ARRAY | VT_UI1);
::SafeArrayAccessData(comInput.parray,&pSrc);
memcpy(resvBuffer.GetData(),pSrc,bufferSize);
::SafeArrayUnaccessData(comInput.parray);
MSCommのGetInputメソッドはVariant型で結果を戻すので、COleVariant型で受け取るのだが、どういう条件かは分からないが、一定条件の文字列において文字列が壊れる。ブレークをかけてみて、メモリダンプ結果を読んでみたのだが、やっぱりGetInputから値が渡ってきた時には既に値が壊れている。
途方にくれていたので、CHUU君&ダークを呼んで3人で考察。あーだのこーだのやっていたところ、MSComm32のプロパティ値が間違っていることが判明。
通信モードがバイナリモードではなくテキストモードで通信していたため、何らかの補正が加えられた模様。
Variantの型が、BYTE(unsigned char)ではなくVT_BSTR(unsinged short)だったのはその為か……orz
そこを直すとあっさりと修正完了。こんな問題に4時間も悩むとは……orz