不过你说SafeArray中的元素不能使用struct这种数据类型,我有点疑惑。我在接口中有这么个函数就是传SAFEARRAY的,元素是自定义的结构。在VB中调用该接口函数也可以成功。
结构定义及函数代码如下:
IDL:
typedef [uuid(5536B87A-57D7-45e3-8A06-9B21BE40F5D2)] struct rcSimu
{
int iSimuNo;
BSTR strSimuName;
}CRcSimu;
typedef [uuid(425091B5-1E6F-4cfb-995C-18AFA20AFA84)] struct rcNode
{
int iUniqueNo;
float fResult;
BSTR strNodeName;
SAFEARRAY(CRcSimu) aRcSimu;
}CNode;
函数:
/*自定义结构的ID*/
const GUID IID_STRUCT_SIMU = { 0x5536b87a, 0x57d7, 0x45e3, { 0x8a, 0x6, 0x9b, 0x21, 0xbe, 0x40, 0xf5, 0xd2 } };
const IID IID_STRUCT_NODE = { 0x425091b5, 0x1e6f, 0x4cfb, { 0x99, 0x5c, 0x18, 0xaf, 0xa2, 0xa, 0xfa, 0x84 } };
STDMETHODIMP CRcTest::GetStruct(SAFEARRAY **pNode)
{
IRecordInfo* pRecordInfo=NULL;
IRecordInfo *pSimuRecordInfo=NULL;
HRESULT hR=GetRecordInfoFromGuids(LIBID_RECON_ATLLib,
1,0,GetUserDefaultLCID(),IID_STRUCT_SIMU
,&pSimuRecordInfo);
if(!SUCCEEDED(hR))
{
return FALSE;
}
hR=GetRecordInfoFromGuids(LIBID_RECON_ATLLib
,1,0,GetUserDefaultLCID(),IID_STRUCT_NODE
,&pRecordInfo);
if(!SUCCEEDED(hR))
{
return FALSE;
}
/*创建大小为5个元素的自定义结构的数组--该结构内还有成员为数组*/
*pNode=SafeArrayCreateVectorEx(VT_RECORD,0,5
,(void *)pRecordInfo);
CNode *pData=0;
hR=SafeArrayAccessData(*pNode,(void **)&pData);
if(!SUCCEEDED(hR))
{
return FALSE;
}
CRcSimu *pSimu=NULL;
for(int i=0;i<5;i++)
{
pData[i].iUniqueNo=i*100*(i+1);
pData[i].fResult=2.2343+i;
/*(CNode 结构的aRcSimu为数组类型) 动态创建aRcSimu的大小*/
pData[i].aRcSimu=SafeArrayCreateVectorEx(VT_RECORD,0,3,(void *)pSimuRecordInfo);
hR=SafeArrayAccessData(pData[i].aRcSimu,(void **)&pSimu);
for(int j=0;j<3;j++)
{
pSimu[j].iSimuNo=(i+1)*10+(j+1);
}
SafeArrayUnaccessData(pData[i].aRcSimu);
}
SafeArrayUnaccessData(*pNode);
pSimuRecordInfo->Release();
pRecordInfo->Release();
return S_OK;
}
下面是VB中的测试函数,在里面动态分配了数组大小,
Dim aSimu() As RECON_ATLLib.rcSimu
Dim i, j, iSum As Integer
Dim objRcTest As RECON_ATLLib.RcTest
Set objRcTest = New RECON_ATLLib.RcTest
Dim aNodes() As RECON_ATLLib.rcNode
objRcTest.GetStruct aNodes
i = UBound(aNodes)
MsgBox "在VC里分配的数组大小为" + CStr(i+1)
MsgBox aNodes(i).fResult
i = UBound(aNodes(0).aRcSimu)
For j = 0 To i
MsgBox "节点1的aRcSimu(" + CStr(j) + ").iSimuNo="
+ CStr(aNodes(0).aRcSimu(j).iSimuNo)
Next
弹出对话框的内容一次为:
“数组大小为5”
“节点1的aRcSimu(0).iSimuNo=11"
“节点1的aRcSimu(0).iSimuNo=12"
“节点1的aRcSimu(0).iSimuNo=13"
符合设想的功能。
To KingSeaMountain():
感谢回答,不过我的问题不是在传参数的问题,初始化接口已经可以传 自定义的结构以及自定义的结构数组了!
问题是:这些自定义的结构 一般都需要FindItem,MoveItem(),AddItem之类的函数,如果另外实现某个接口通过分别传这些结构或结构的数组作参数来操作他们,使用起来很不方便和自然。 也就是说:客户端的易使用性和符合习惯是最重要的!
根据上面诸位的回答我想将结构做成对应的接口是最好的办法!这样可以封装这些函数,而且可以隐藏结构具体使用的数据成员!可惜就是性能上损失不少。