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 ...
随机推荐
- Rsync 服务器搭建
Rsync简介 rsync 是一个 Unix 系统下的文件同步和传输工具. 它具备以下特性: 1. 能更新整个目录和树和文件系统 2. 有选择性的保持符号链链.硬链接.文件属于.权限.设备以及时间 等 ...
- Re:从 0 开始的微服务架构--(四)如何保障微服务架构下的数据一致性--转
原文地址:http://mp.weixin.qq.com/s/eXvoJew3bjFKzLLJpS0Otg 随着微服务架构的推广,越来越多的公司采用微服务架构来构建自己的业务平台.就像前边的文章说的, ...
- Web Api和Asp.Net mvc post请求区别
这是mvc的,mvc的post请求可以这样写参数,但是web api的不行.而且content_type:"application/json" 必须要写 下面这是web api的: ...
- windows下安装reidis
下载windows下redis安装包 https://github.com/MSOpenTech/redis/releases 这时候另启一个cmd窗口,原来的不要关闭,不然就无法访问服务端了. 切换 ...
- T7315 yyy矩阵折叠(长)
题目背景 全场基本暴零 题目描述 输入输出格式 输入格式: 如图 输出格式: 如图 输入输出样例 输入样例#1: 2 2 1 -2 3 -4 输出样例#1: 4 输入样例#2: 2 5 1 -2 -3 ...
- Django路由URL
URL配置(URLconf)就像Django所支撑网站的目录.URL与要为该URL调用的视图函数之间的映射表. URLconf配置 样式: from django.conf.urls import u ...
- Swoole 源码分析——进程管理 Swoole_Process
前言 swoole-1.7.2 增加了一个进程管理模块,用来替代 PHP 的 pcntl 扩展. PHP自带的pcntl,存在很多不足,如 pcntl 没有提供进程间通信的功能 pcntl 不支持重定 ...
- LCA题集
点的距离(模板题) 树中两点间的距离就是d[u] + d[v] - 2 * d[lca(u, v)] #include<bits/stdc++.h> #define REP(i, a, b ...
- 【codeforces 812B】Sagheer, the Hausmeister
[题目链接]:http://codeforces.com/contest/812/problem/B [题意] 一个老大爷在一楼; 然后他有n楼的灯要关(最多n楼); 每楼有m个房间; 给出每个房间的 ...
- java中的接口中的方法
题目如下:(多选题)请选择以下接口定义正确的方法() A:public static void main (String[] args); B:private void test(); C:publi ...