WindowsプログラマのWebアプリへの挑戦日記。あとパンとか。

BYTEの配列データをVARIANTのSAFEARRAY(VT_ARRAY)に変換する

1月 31st, 2008 Posted in C++

今回は、C++に関するエントリー。本業はC++なので、こういうのもありかなと。

VARIANTにデータを設定するのはいつもついつい調べ直してしまいます。今回は、BYTE型のデータをSAFEARRAY型に流し込む方法。調べ直していたところ、ORiN協議会◇技術解説の説明がとてもわかりやすかったので、うれしさついでに関数化してみました。

  1. BOOL ByteArrayToVariant(BYTE* pBytes, int size, VARIANT& v)
  2. {
  3.     SAFEARRAYBOUND rgb[1];
  4.     rgb[0].cElements = size;
  5.     rgb[0].lLbound = 0;
  6.  
  7.     SAFEARRAY* psa = SafeArrayCreate(VT_UI1,1, rgb);
  8.     if(!psa)
  9.         return FALSE;
  10.  
  11.     void HUGEP *pvData;
  12.     HRESULT hr = SafeArrayAccessData(psa, &pvData);
  13.     if(S_OK!=hr)
  14.         return FALSE;
  15.  
  16.     memcpy( pvData, pBytes, size );
  17.  
  18.     hr = SafeArrayUnaccessData(psa);
  19.     if(S_OK!=hr)
  20.         return FALSE;
  21.  
  22.     v.parray = psa;
  23.     v.vt = VT_ARRAY | VT_UI1;
  24.  
  25.     return TRUE;
  26. }

関数の説明

  1. SAFEARRAYBOUND rgb[1];

SAFEARRAYBOUNDは、SAFEARRAYの要素数とインデックスの下限値を設定する。BOUNDには「限度,範囲」なんて意味があるので、わかりやすいネーミングですね。次に、

  1. SAFEARRAY* psa = SafeArrayCreate(VT_UI1,1, rgb);

で、SAFEARRAYの実体を作ります。今回は、BYTEの配列なのでVT_UI1を指定します。SAFEARRAYのデータへは、SafeArrayAccessData()をコールすることでアクセスできるようになります。

  1. void HUGEP *pvData;
  2. HRESULT hr = SafeArrayAccessData(psa, &pvData);

コピー元のデータをSafeArrayAccessData()で取得した配列へコピーします。

  1. memcpy( pvData, pBytes, size );

SafeArrayAccessData()したら必ず、SafeArrayUnaccessData()をコールします。

  1. hr = SafeArrayUnaccessData(psa);

最後にVARIANT型の引数にデータを設定しておしまいです。

  1. v.parray = psa;
  2. v.vt = VT_ARRAY | VT_UI1;

ByteArrayToVariant()の呼び元でVARIANTを使った後に、

  1. HRESULT SafeArrayDestroy( v.parray );

をコールするとなんか不適切なメモリを解放してしまうようで、なんとなく不安定になりました。なんででしょうねぇ。

こちらもオススメ!

Trackback URL

Post a Comment