STL数组和com数组相互转换的做法
作者:朱金灿
来源: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控件中传入字符串数组的有关问题
STL数组和com数组相互转换的做法的更多相关文章
- hdu5438 Ponds[DFS,STL vector二维数组]
目录 题目地址 题干 代码和解释 参考 题目地址 hdu5438 题干 代码和解释 解答本题时参考了一篇代码较短的博客,比较有意思,使用了STL vector二维数组. 可以结合下面的示例代码理解: ...
- 关于数组和List之间相互转换的方法
1.List转换成为数组:返回数组的运行时类型.如果列表能放入指定的数组.否则,将根据指定数组.如果指定的数组的元素比列表的多),那么会将存储列表元素的数组. 返回:包含列表元素的list.add(& ...
- C语言数组:C语言数组定义、二维数组、动态数组、字符串数组
1.C语言数组的概念 在<更加优美的C语言输出>一节中我们举了一个例子,是输出一个 4×4 的整数矩阵,代码如下: #include <stdio.h> #include &l ...
- 【嵌入式开发】C语言 指针数组 多维数组
. 作者 : 万境绝尘 转载请注明出处 : http://blog.csdn.net/shulianghan/article/details/21402047 . 1. 地址算数运算示例 指针算数运算 ...
- 数组转集合、集合转数组、字符串数组与int型、long型数组等的转换
在项目中经常会遇到数组转集合.集合转数组.数组之间类型转换等操作 1.数组转集合 为了实现把一个数组转换成一个ArrayList,很多Java程序员会使用如下的代码: String str[] = { ...
- C语言 指针数组 多维数组
. 作者 : 万境绝尘 转载请注明出处 : http://blog.csdn.net/shulianghan/article/details/21402047 . 1. 地址算数运算示例 指针算数运算 ...
- PHP如何判断一个数组是一维数组或者是二维数组?用什么函数?
如题:如何判断一个数组是一维数组或者是二维数组?用什么函数? 判断数量即可 <?php if (count($array) == count($array, 1)) { echo '是一维数组' ...
- 数组去重及数组的prototype原型
Array.prototype.check= function(){ for(var i=0;i<this.length;i++){ for(var j=i+1;j<this.length ...
- PChar,PAnsiChar,String,AnsiString,Char数组,AnsiChar数组转换
PChar,PAnsiChar,String,AnsiString,Char数组,AnsiChar数组之间的转换关系见下图 通过转换链,可以实现任意两个类型之间的互转.如PChar转PAnsiChar ...
随机推荐
- golang sftp传输文件
之前有一篇介绍如何使用 golang 通过SSH协议来执行远程命令:golang执行远程命令 同样,通过SSH协议也可以使用 golang 来远程传输文件. 除了 SSH 的库,为了传输文件,还需要用 ...
- Oracle学习系类篇(四)
.分析函数 分析函数oracle专门用于解决复杂报表统计需求的功能强大的函数,它可以在数据中进行分组,然后计算基于组的邹忠统计值,并且每一组的每一行都可以返回一个统计值. 分析函数和聚合函数的不同之处 ...
- 去除input 在 webkit内核浏览器 选择历史时,有一个黄色背景
input:-webkit-autofill { -webkit-box-shadow: 0 0 0px 1000px white inset; } http://www.imooc.com/arti ...
- php方法----将数组按照键值进行排序
将数组按照键值进行排序 array_multisort(array_column($arr,'first'),SORT_ASC,$arr);
- JS自定义功能函数实现动态添加网址参数修改网址参数值
无论是前端开发还是后台设计,很多时候开发人员都需要获取当前或目标网址的相关信息.这个已有现成的内置对象属性可以直接调用了(下面是获取当前页面的参考代码) 复制代码 代码如下: <script t ...
- 测试用html
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...
- 一些html5
---匿名函数(funcation(){}())---- 一.拖拽 draggable=ture-----A拖动元素上事件 1. 拖拽开始:ondragstart2. 拖拽中:ondrag3. 拖拽结 ...
- BZOJ 4006 [JLOI2015]管道连接(斯坦纳树+子集DP)
明显是一道斯坦纳树的题. 然而这题只需要属性相同的点互相连接. 我们还是照常先套路求出\(ans[s]\). 然后对\(ans[s]\)做子集DP即可. 具体看代码. #include<iost ...
- SA 学习笔记
后缀数组是解决字符串问题的有力工具--罗穗骞 后缀数组是对字符串的后缀排序的一个工具, sa将排名为i的字符串的开头位置记录下来, rnk将开头位置为i的字符串的排名记录下来. https://www ...
- 硬核官宣:台积电官宣6nm及7nm加强版工艺!
台积电正式宣布了6nm(N6)工艺,在已有7nm(N7)工艺的基础上大幅度增强,号称可提供极具竞争力的高性价比,而且能加速产品研发.量产.上市速度. 这几年,曾经执行业牛耳的Intel在新工艺方面进展 ...