STL数组和com数组相互转换的做法
2015-06-14 12:42
169 查看
作者:朱金灿
来源:http://blog.csdn.net/clever101
STL的泛型数组是vetor,com的泛型数组类型是VARIANT。二者怎样能相互转化呢?就是说怎么把一个vector对象封装进VARIANT对象,又怎么将VARIANT对象封装进vector对象。经过一番研究,找到了办法。需要注意的是,数值数组和字符串数组是需要单独处理的。首先谈谈数组类型的数组如何转换,比如std::vector<int>转换为一个VARIANT对象。需要一个模板类来实现,代码如下:
测试函数如下:
这里需要注意的是,com只支持unicode字符,所以对应的stl字符串数组类型为std::vector<std::wstring>。
测试函数如下:
1. 关于在C#中调用MFC编写Activex控件中传入字符串数组的有关问题
来源:http://blog.csdn.net/clever101
STL的泛型数组是vetor,com的泛型数组类型是VARIANT。二者怎样能相互转化呢?就是说怎么把一个vector对象封装进VARIANT对象,又怎么将VARIANT对象封装进vector对象。经过一番研究,找到了办法。需要注意的是,数值数组和字符串数组是需要单独处理的。首先谈谈数组类型的数组如何转换,比如std::vector<int>转换为一个VARIANT对象。需要一个模板类来实现,代码如下:
template<class T> class CVariantPack { private: CVariantPack(void){}; ~CVariantPack(void){}; public: static bool SetTPtrVariant(VARENUM ElementType,const std::vector<T>& vecData,VARIANT &vdata) { try { if(vecData.empty()) { return false; } SAFEARRAYBOUND rgsabound[1]; rgsabound[0].lLbound = 0; rgsabound[0].cElements = (ULONG)vecData.size(); SAFEARRAY *psa = SafeArrayCreate(ElementType,1, rgsabound ); if( psa ) { for( long i=0; i<(long)vecData.size(); i++ ) { SafeArrayPutElement( psa, &i, (void *)(&vecData[i])); } vdata.vt = VT_ARRAY|ElementType; vdata.parray = psa; SafeArrayUnaccessData( psa ); return true; } else { return false; } } catch(...) { return false; } } static int GetTPtrVariant (VARENUM ElementType,std::vector<T>& vecData,const VARIANT vdata) { try { if( vdata.vt==VT_NULL || vdata.vt==VT_EMPTY ) { return -1; } if( !(vdata.vt & VT_ARRAY) ) { return -2; } SAFEARRAY *psa = vdata.parray; UINT nDims = SafeArrayGetDim( psa ); if( nDims != 1 ) { return -3; } //检查数组元素类型 VARTYPE vt = 0; SafeArrayGetVartype( psa, &vt ); if( vt != ElementType ) { return -4; } //检查数组上下限和元素个数是否为偶数个 LONG lUBound =0, lLBound = 0; SafeArrayGetUBound( psa, 1, &lUBound ); SafeArrayGetLBound( psa, 1, &lLBound ); int lElements = lUBound - lLBound + 1; if( lElements <= 0 ) { return -5; } T *pTmp = NULL; SafeArrayAccessData( psa, (void **)&pTmp ); if( NULL == pTmp ) { return -6; } for (int i = 0;i<lElements;i++) { vecData.push_back(*(pTmp+i)); } SafeArrayUnaccessData( psa ); return lElements; } catch(...) { return -1; }; } };
测试函数如下:
bool TestVariantPack1(void) { std::vector<long> a; a.push_back(1); a.push_back(2); a.push_back(3); VARIANT vdata; //long 数组封装到variant if( !CVariantPack<long>::packtptrvariant(v_long,a,3,vdata)) { return false; } std::vector<long> b; //从variant获取long数组数据 int num= CVariantPack<long>::GetTPtrVariant(VT_I4,b,vdata); if( num<=0 ) { return false; } }下面再谈谈字符串数组的相互转换。
// std::vector< std::wstring>转换为一个VARIANT对象 bool StringArrayToVariant(const std::vector< std::wstring >& vecData,VARIANT& vdata) { if(vecData.empty()) { return false; } SAFEARRAY *psa; SAFEARRAYBOUND rgsabound; rgsabound.cElements = (ULONG)vecData.size(); rgsabound.lLbound = 0; psa = SafeArrayCreate(VT_BSTR, 1, &rgsabound);//设置为一位BSTR数组 if( psa ) { BSTR* bstrArray; ::SafeArrayAccessData(psa,(void**)&bstrArray);//将数据引出进行操作,并加锁 for (int i = 0 ; i < vecData.size(); ++i) { // bstrArray[i] = arExport[i].AllocSysString(); // 如果是std::vector<CString>,请用这句代码 bstrArray[i] = const_cast<TCHAR*>(vecData[i].c_str()); } vdata.vt = VT_ARRAY|VT_BSTR; vdata.parray = psa; ::SafeArrayUnaccessData(psa); return true; } return false; } //VARIANT对象转换为std::vector< std::wstring> int VariantToStringArray(const VARIANT& vdata,std::vector<std::wstring >& vecData) { if( vdata.vt==VT_NULL || vdata.vt==VT_EMPTY ) { return -1; } if( !(vdata.vt & VT_ARRAY) ) { return -2; } SAFEARRAY *psa = vdata.parray; UINT nDims = SafeArrayGetDim( psa ); if( nDims != 1 ) { return -3; } //检查数组元素类型 VARTYPE vt = 0; SafeArrayGetVartype( psa, &vt ); if( vt != VT_BSTR ) { return -4; } //检查数组上下限和元素个数是否为偶数个 LONG lUBound =0, lLBound = 0; SafeArrayGetUBound( psa, 1, &lUBound ); SafeArrayGetLBound( psa, 1, &lLBound ); int lElements = lUBound - lLBound + 1; if( lElements <= 0 ) { return -5; } BSTR* pTmp = NULL; SafeArrayAccessData( psa, (void **)&pTmp ); if( NULL == pTmp ) { return -6; } for (int i = 0;i<lElements;i++) { vecData.push_back(*(pTmp+i)); } SafeArrayUnaccessData( psa ); return lElements; }
这里需要注意的是,com只支持unicode字符,所以对应的stl字符串数组类型为std::vector<std::wstring>。
测试函数如下:
bool TestVariantPack(void) { std::vector<std::wstring> vecString; vecString.push_back(_T("HelloWorld")); vecString.push_back(_T(",")); vecString.push_back(_T("I am from China!")); VARIANT vdata; // std::vector<std::wstring> 数组封装到variant if( !SysUtility::StringArrayToVariant(vecString,vdata)) { return false; } std::vector<std::wstring> vecString2; //从variant获取std::vector<std::wstring>数组数据 int num= SysUtility::VariantToStringArray(vdata,vecString2); if( num<=0 ) { return false; } return true; }参考文献:
1. 关于在C#中调用MFC编写Activex控件中传入字符串数组的有关问题
相关文章推荐
- 智能视频分析
- 题目1160:放苹果
- LCS算法的两种JAVA实现方式
- Json转换利器Gson之实例一-简单对象转化和带泛型的List转化
- software testing
- 概率统计:条件独立
- UpdatePanel的用法详解
- JSP(3) ----JDBC编程2
- 散列表之链接法
- Python之PyQT4的使用技巧集锦
- java String对象是“引用”传递的
- 掺合模式(Mixin)
- 四则运算 用户调之修改篇
- MDI窗体简单方法(调用,闪屏)
- Unity中 Plugin 跨语言 类型转换
- Java基础之I/O详解(一)File篇
- FaceBook/infer-分析Android项目
- Android SD卡文件读写目录及权限
- 自定义透明背景的Actionbar
- Verification and validation