VARIANT(vt = VT_BSTR | VT_ARRAY)の値をchar型の文字列変数に格納するには?

解決


どら  2005-04-23 09:19:40  No: 57166

毎度すみません・・・

COMの関数を用いてある値を取得しようと思っています。
返ってくる値はVARIANT型なのですが・・・

vt = VT_BSTR

の時は、問題なくchar型に変換して値を取ることができたのですが、

vt = VT_BSTR | VT_ARRAY

とString ARRAYで返ってきた場合にchar型に変換したいのですが・・・
流れとしては

VARIANT v;
char c[適当な長さ];
int n;

VARIANTを返す関数(&v);

if(v.vt==VT_BSTR | VT_ARRAY)
{
  ARRAYの要素数を返す関数(n);         //←SafeArrayGetDim()??

  for(int x = 0; x < n; x++)
  {
     ARRAY→charに取り込む関数(c);
     MessageBox(NULL, c, "結果", MB_OK);
  }
}

といった感じです(とりあえずは・・・)。
SAFEARRAYの取り扱い方が全くわからなくて・・・。
この中の文字列はワイド文字?マルチバイト?そんなところからわかっていないです・・・。

どなたかご教授いただけないでしょうか?
参考ページなどでもかまいません。
どなたか教えてください(^^;

よろしくお願いします。


forty-five  2005-04-24 09:17:54  No: 57167

COleSafeArray でググるといいかも。
MFC 使わない場合でも, これのソース見れば大体分かると思います。


どら  2005-04-30 00:31:35  No: 57168

forty-five さん
レスありがとうございます。

あれから色々と調べてみて、こんな感じの関数を作ってみました。

int read_array(VARIANT& vstr,char *ptr, int szptr)
{
  VARIANT args = vstr;
  VARTYPE vt = V_VT(&args);
  
  if (vt == (VT_VARIANT | VT_BYREF))
  {
    args = *args.pvarVal;
    vt = V_VT(&args);
  }
  
  int bArray = vt & VT_ARRAY;
  if(!bArray)// not array
  {
    return 0;
  }
  SAFEARRAY *psa = NULL;
  HRESULT hr;
  LONG cElements, lLBound, lUBound;
  WCHAR *pdata;
  psa = V_ARRAY(&args);

  if(SafeArrayGetDim(psa) != 1)
  {
    return 0;
  }

  hr = SafeArrayGetLBound(psa, 1, &lLBound);
  if (FAILED(hr))
  {
    return 0;
  }
  
  hr = SafeArrayGetUBound(psa, 1, &lUBound);
  if (FAILED(hr))
  {
    return 0;
  }

  hr = SafeArrayAccessData(psa, (LPVOID*)&pdata);
  if (FAILED(hr))
  {
    return 0;
  }

  cElements = lUBound-lLBound + 1;

  WideCharToMultiByte(CP_ACP, 0, pdata, -1, ptr, szptr, NULL, NULL);
  hr = SafeArrayUnaccessData(psa);
  return cElements;
}

一部エラー処理は抜いているところがありますが・・・。
結局値がうまく取れません。

この関数のなかでウオッチしても、やっぱり取得できていないようでした・・・。

どなたかご存じの方、アドバイスをお願いします。


forty-five  2005-05-01 10:50:27  No: 57169

とりあえず pdata の型がおかしいです。
文字列の配列なら, BSTR* にしないとダメです。


どら  2005-05-03 21:15:08  No: 57170

forty-fiveさん

ありがとうございます!!
下記ソースで解決です!!

本当にありがとうございました!!!!

後は、必要なエラー処理などを追加して・・・
形が見えてきました。
本当にありがとうございました。

int read_array(VARIANT& vstr,char *ptr, int szptr)
{
  VARIANT args = vstr;
  VARTYPE vt = V_VT(&args);
  
  // check VARIANT REFERENCE
  if (vt == (VT_VARIANT | VT_BYREF))
  {
    args = *args.pvarVal;
    vt = V_VT(&args);
  }
  
  int bArray = vt & VT_ARRAY;
  if(!bArray)// not array
  {
    return 0;
  }
  SAFEARRAY *psa = NULL;
  HRESULT hr;
  LONG cElements, lLBound, lUBound;
  BSTR *pdata;
  psa = V_ARRAY(&args);
  // Check dimensions of the array.
  if(SafeArrayGetDim(psa) != 1)
  {
    return 0;
  }

    // Get array bounds.
  hr = SafeArrayGetLBound(psa, 1, &lLBound);
  if (FAILED(hr))
  {
    return 0;
  }
  
  hr = SafeArrayGetUBound(psa, 1, &lUBound);
  if (FAILED(hr))
  {
    return 0;
  }

  // Get a pointer to the elements of the array.
  hr = SafeArrayAccessData(psa, (LPVOID*)&pdata);
  if (FAILED(hr))
  {
    return 0;
  }

  // element count.
  cElements = lUBound-lLBound + 1;
  // put array data
  WideCharToMultiByte(CP_ACP, 0, *pdata, -1, ptr, szptr, NULL, NULL);
//  *ptr = pdata;
  hr = SafeArrayUnaccessData(psa);
  return cElements;
}


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加