问题的提出:
近期在编程时,需要将数组表示的数据通过ActiveX或COM控件接口传入到控件的内部,由于ActiveX或COM控件接口是跨语言的,故不能将ActiveX或COM控件接口的参数简单地定义为指针。为了支持跨语言访问,必须将ActiveX或COM控件接口的参数定义为变体类型,即VARIANT。代码如下:
调用方:
// 组织数据
m_plDataBuf = new LONG[nDataCnt];
auto_ptr<LONG> ptrDataBuf(m_plDataBuf);
// 给数组赋值
for(vector<int>::size_type i = 0; i < nDataCnt; ++i)
{
m_plDataBuf[i] = vtData[i];
}
// 将数据通过VARIANT的SAFEARRAY数组传入。其中m_varBuffer为VARIANT类型
m_pArray = NULL; // m_pArray 为SAFEARRAY* 类型
HRESULT hr = SafeArrayAllocDescriptor(1, &m_pArray);//创建SAFEARRAY结构的对象
m_pArray->cDims = 1; // 数组维数
m_pArray->cbElements = sizeof(LONG); // 每个元素占用的字节数
m_pArray->rgsabound[0].cElements = nDataCnt; // 第0维的元素个数
m_pArray->rgsabound[0].lLbound = 0; // 第0维数组起始下标
m_pArray->pvData = m_plDataBuf; // 真实的数据
m_pArray->fFeatures =FADF_AUTO|FADF_FIXEDSIZE; //FADF_AUTO指定在栈上分配数据,并且大小不可以改变
m_varBuffer.vt = (VT_ARRAY | VT_VARIANT); // 注意:SAFEARRAY的类型格式必须是这样
m_varBuffer.parray = m_pArray; // 将普通数据赋值给SAFEARRAY数组。
// 设置数据源。m_spMeSampleCE为ActiveX或COM控件接口类,SetDataSource为接口类方法
m_spMeSampleCE->SetDataSource(m_varBuffer);
被调用方:ActiveX或COM控件接口函数设计:
VARIANT_BOOL CECGView::SetDataSource(VARIANT &varDataBuf)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
if(varDataBuf.vt != ((VT_ARRAY | VT_VARIANT))) // 数据类型不是SAFEARRAY类型
return VARIANT_FALSE;
ClearDataSource();
LONG uHighBound = 0, uLowBound = 0;
// 获取数据个数
::SafeArrayGetLBound(varDataBuf.parray, 1, &uLowBound);
::SafeArrayGetUBound(varDataBuf.parray, 1, &uHighBound);
m_nBufLen = uHighBound - uLowBound + 1;
// m_pDataBuf不能自己new出来。SafeArrayAccessData函数内部会new出一个,所以下句注释的代码是不能要的,否则出错。
// m_pDataBuf = new LONG [m_nBufLen ];
HRESULT hr = SafeArrayAccessData(varDataBuf.parray, (void**)&m_pDataBuf);
if(FAILED(hr))
return VARIANT_FALSE;
// 注意:只有取出来的数据m_pDataBuf 用完后才能调用这个函数,该函数调用后会使m_pDataBuf 缓冲区无效。
// SafeArrayUnaccessData(m_parray);
return VARIANT_TRUE;
}
联系客服