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が発生し、
「追加情報:マネージ値クラスに指定されたレコードをマップできません」
と表示されます。
どなたかよろしくお願いします。
SafeArrayCreateExではなくSafeArrayAllocDescriptor、SafeArrayAllocDataをつかって
SAFEARRAY構造体のcbElementsメンバを設定してみてはどうでしょうか?
過去ログ
http://madia.world.coocan.jp/vb/vb_bbs2/200509/200509_05090039.html
俺はCOMを使ったVBとやり取りするプッログラム作ってないからよくわからない。そんな俺の回答だからおかしなこと言っているかもしれないけど。
構造体配列をVARIANTで渡せたっけ?
検索してみたけど結果報告のない話が多いな。
XXX::GetHogeって何?
STDMETHODIMP XXX::GetHoge(VARIANT* vOut, long *nRet )
vOut, nRet に答えをいれていないように見えるんだけど。
不明な変数がある。
ツイート | ![]() |