人気ブログランキング | 話題のタグを見る
Windows 2000 では、VT_I8 が使えない
Windows XPでとあるソフトを開発していますが、Windows 2000で実行すると原因不明のエラーが発生するという報告がありました。
エラー内容は、

Run time error!
program abnormal termination.

とのこと。
来た!Run time errorは、原因が分かりにくい。
エラーメッセージも、いつも同じだし。
エラーが出るタイミングは判っているので、その周りを調査した。

ソースを眺めていても、全く原因が分からなかったので、どこでエラーが起きているのか確認する事にした。
Windows 2000の開発環境が手元になかったので、開発環境が入っていないWindows 2000にXPの開発環境で AfxMessageBox でデバッグ情報を出力できるようにしたバージョンをコピーして実行。
何度かやっている内に、ある処理に行き着いた。
次のような処理。
void CXxx::Set(CString strKey, _variant_t varValue)
{
m_mapKeyVal[strKey] = varValue;
// ↑ std::map
}


全く問題ないように見えるけど、実はWindowsの仕様の不一致が原因で、個々でエラーが発生していた。

この関数にデータを渡す時に、次のようなコードを使っていた。

__int64 nSize = 0;
if(<ファイルサイズを取得関数>(&nSize))
{
Set("FileSize", nSize);
}


Windows XPでは、全く問題なく動作するが、Windows 2000のCOM(ActiveX)では、64ビットの整数型(VT_I8, VT_UI8)がサポートされていないので、 m_mapKeyVal[strKey] = varValue を実行したときにエラー(例外 _com_error がスローされる)が発生していた。

代入時点で例外が発生しないのは、コンストラクタで例外を発生させてしまうと、いろいろと問題があるため。
参考:C MAGAZINE - プログラミングの禁じ手Web版 C++編 - 例外に関するパターン
だけど、ここで例外が発生しないと、追跡が難しくなる気がする。しょうがないか。

とりあえず、__int64 を double にキャストする事で一時しのぎすることとなった。

Set("FileSize", (double)nSize);

ソニーストア

by isoq | 2006-07-28 11:43 | C/C++/Win32
<< デスクトップのスクリーンキャプ... カブトムシとの愛を確かめ合った日 >>