_variant_t を使用して、楽して安全にデータ変換

VBやVBA/JavaScriptなどでは、バリアント型というのがあって、どんな値も同じように楽に扱う事が出来ます。
変換もほとんど勝手にやってくれます。うらやましいですね。
でも大丈夫!VCでもバリアント型を使う事が出来ます!というお話。

Microsoft固有ですが、_variant_t という COM による VARIANT のサポートクラスを使用する事で、面倒な型間データ変換を安全に行う事が出来ます。
自分で実装すると、いろいろと問題が起こりがちです。
自分よりも優れた他人が作ったものを信用しよう!という趣旨で、行ってみます。

最初に _variant_t をお好みの値で初期化します。
_variant_t は バリアント型なので、(語弊はありますが)どんな値でも入れる事が出来ます。
数値で初期化するには、
_variant_t vVal((long)100);
などとします。
キャストしているのは、その値が整数型なのか、浮動小数点型なのか、それとももっと別の型(ポインタとか)なのかをはっきりさせるためです。
C++では、こういうキャストを行わないと、選択肢が複数有るため、コンパイラが困ってしまいます。
C++のコンパイラは勝手に判断してくれません。
この辺が語弊です。

初期化が終わったら、_variant_t::ChangeType() 関数を使用してデータを変換します。
ここで、変換後の型を指定します。
 VT_BSTR・・・UNICODE文字列型(bstrVal)
 VT_DATE・・・日付型(date)
 VT_I4・・・長整数型(lVal)
 ※括弧内は、その型のメンバ名です

あとは、変換後のデータが入った_variant_t のメンバ変数にアクセスするだけです。
    // 数値から文字列へ
    _variant_t vInt((long)100);
    try
    {
        vInt.ChangeType(VT_BSTR);
        CString strInt(vInt.bstrVal);
        AfxMessageBox(strInt);
    }
    catch(_com_error& e)
    {
        AfxMessageBox("数値の書式が不正です");
    }

    // 日付文字列から日付へ
    _variant_t vDateTime("2005/02/28 10:10:10");
    try
    {
        vDateTime.ChangeType(VT_DATE);
        COleDateTime oleDateTime(vDateTime.date);
        AfxMessageBox(oleDateTime.Format("%Y/%m/%d %H:%M:%S"));
    }
    catch(_com_error& e)
    {
        AfxMessageBox("日付の書式が不正です");
    }

確かに、変換は出来ました。
しかも、他人が作ったという安心感もあります。

_varinat_t にて変換を行うときには、try ~ catch 構文を使用する必要があります。
変換エラーの時には、COMの例外を投げてくるからです。
catch しないと、変換エラーのためにアプリケーションエラーでアプリが落ちてしまいます。

ちなみに、comdef.h をインクルードする必要があります。

あまり便利じゃないですね。
[PR]
by isoq | 2005-06-30 16:23 | C/C++/Win32
e87.com(千趣会イイハナ) 花を贈るなら日比谷花壇
<< SBS2003は、自動シャット... 吊り橋は、結構恐かった。 >>