COMで構造体配列をVARIANTで返す方法


satoshi  2009-02-17 06:32:09  No: 69702

VisualStudio.NET 2003 でVB & VCを使用しています。
WindowsXP SP3です。

VCでCOMを作成しています。
VBでCOMを利用したサンプルを作って動作確認しています。
構造体配列をVARIANTで返したいのですが、うまくいきません。
どなたか知恵をお貸しください。

コードは次のような感じです(かなりはしょってます。)
---
[ C++側 ]
// 構造体
[export,library_block,uuid(xxxx-xxxx...)]
struct HogeStruct1
{
  LONG v1;
  LONG v2;
};

[export,library_block,uuid(xxxx-yyyy...)]
struct HogeStruct2
{
  HogeStruct1 hoge;
  BSTR bstr;
};

//インターフェースクラスのメソッド
STDMETHODIMP XXX::GetHoge(VARIANT* vOut, long *nRet )
{
  ITypeLib *pLib;
  LoadRegTypelib( CAtlModule::m_libid, 1,0,GetUserDefaultLCID(),&pLib);

  ITypeInfo *pInfo;
  pLib->GetTypeInfoOfGuid( GUIDofStruct, &pInfo);

  IRecordInfo *pRec;
  GetRecordInfoFromTypeInfo(pTypeInfo, &pRec);

  SAFEARRAYBOUND b = {2,0};
  SAFEARRAY *psa = SafeArrayCreateEx(VT_RECORD, 1, &b, pRec );

  HogeStruct*pData;
  SafeArrayAccessData(psa, (void**)&pData );

  pData[0].hoge.v1 = 1;
  pData[0].hoge.v2 = 100;
  pData[0].b = ::SysAllocString("hoge1")
  pData[1].hoge.v1 = 2;
  pData[1].hoge.v2 = 200;
  pData[1].b = ::SysAllocString("hoge2")

  SafeArrayUnaccessData( psa );

  VariantClear(vOut);
  VariantInit(vOut);

  pVar->vt = VT_ARRAY | VT_RECORD;
  pVar->parray = psa;

  return S_OK;
}
---
[ VB側 ]
Dim obj As Hoge.XXX
Dim vvv As Object
set obj = New Hoge.XXX
obj.GetHoge(vvv)

Debug.Print vvv(0).hoge.v1.ToString() 
Debug.Print vvv(0).hoge.v2.ToString() 
Debug.Print vvv(0).bstr
Debug.Print vvv(1).hoge.v1.ToString() 
Debug.Print vvv(1).hoge.v2.ToString() 
Debug.Print vvv(1).bstr

obj = Nothing

---

コンパイルまでうまくいき、動作確認したところ、XXX::GetHogeメソッドは正常に終了しているようです。
ですが、VB側の obj.GetHoge(vvv)でExceptionが発生し、

「追加情報:マネージ値クラスに指定されたレコードをマップできません」

と表示されます。

どなたかよろしくお願いします。


Blue  2009-02-17 18:00:31  No: 69703

SafeArrayCreateExではなくSafeArrayAllocDescriptor、SafeArrayAllocDataをつかって
SAFEARRAY構造体のcbElementsメンバを設定してみてはどうでしょうか?

過去ログ
http://madia.world.coocan.jp/vb/vb_bbs2/200509/200509_05090039.html


wclrp ( 'o')  2009-02-17 18:01:58  No: 69704

俺はCOMを使ったVBとやり取りするプッログラム作ってないからよくわからない。そんな俺の回答だからおかしなこと言っているかもしれないけど。

構造体配列をVARIANTで渡せたっけ?
検索してみたけど結果報告のない話が多いな。

XXX::GetHogeって何?
STDMETHODIMP XXX::GetHoge(VARIANT* vOut, long *nRet )
vOut, nRet に答えをいれていないように見えるんだけど。
不明な変数がある。


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

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






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