BYTEの配列データをVARIANTのSAFEARRAY(VT_ARRAY)に変換する
1月 31st, 2008 Posted in C++今回は、C++に関するエントリー。本業はC++なので、こういうのもありかなと。
VARIANTにデータを設定するのはいつもついつい調べ直してしまいます。今回は、BYTE型のデータをSAFEARRAY型に流し込む方法。調べ直していたところ、ORiN協議会◇技術解説の説明がとてもわかりやすかったので、うれしさついでに関数化してみました。
- BOOL ByteArrayToVariant(BYTE* pBytes, int size, VARIANT& v)
- {
- SAFEARRAYBOUND rgb[1];
- rgb[0].cElements = size;
- rgb[0].lLbound = 0;
- SAFEARRAY* psa = SafeArrayCreate(VT_UI1,1, rgb);
- if(!psa)
- return FALSE;
- void HUGEP *pvData;
- HRESULT hr = SafeArrayAccessData(psa, &pvData);
- if(S_OK!=hr)
- return FALSE;
- memcpy( pvData, pBytes, size );
- hr = SafeArrayUnaccessData(psa);
- if(S_OK!=hr)
- return FALSE;
- v.parray = psa;
- v.vt = VT_ARRAY | VT_UI1;
- return TRUE;
- }
関数の説明
- SAFEARRAYBOUND rgb[1];
SAFEARRAYBOUNDは、SAFEARRAYの要素数とインデックスの下限値を設定する。BOUNDには「限度,範囲」なんて意味があるので、わかりやすいネーミングですね。次に、
- SAFEARRAY* psa = SafeArrayCreate(VT_UI1,1, rgb);
で、SAFEARRAYの実体を作ります。今回は、BYTEの配列なのでVT_UI1を指定します。SAFEARRAYのデータへは、SafeArrayAccessData()をコールすることでアクセスできるようになります。
- void HUGEP *pvData;
- HRESULT hr = SafeArrayAccessData(psa, &pvData);
コピー元のデータをSafeArrayAccessData()で取得した配列へコピーします。
- memcpy( pvData, pBytes, size );
SafeArrayAccessData()したら必ず、SafeArrayUnaccessData()をコールします。
- hr = SafeArrayUnaccessData(psa);
最後にVARIANT型の引数にデータを設定しておしまいです。
- v.parray = psa;
- v.vt = VT_ARRAY | VT_UI1;
ByteArrayToVariant()の呼び元でVARIANTを使った後に、
- HRESULT SafeArrayDestroy( v.parray );
をコールするとなんか不適切なメモリを解放してしまうようで、なんとなく不安定になりました。なんででしょうねぇ。
こちらもオススメ!