COM组件开发笔记--字符串数组的传递

COM编程的好处就是可以跨语言,我们公司是用C#做开发的,所以用C++去开发COM组件就可以弥补图形渲染性能上的不足。但COM组件也有它的缺点,就是COM接口本身的调用开销比较大,所以我总结了,使用COM组件最好是通过最少次数的接口调用来达到目的。所以数组的传递就至关重要了。打个最简单的比方,调10000次SetX( double x )花的时间肯定要比一次性把x数组传进去SetX( double[] x )多的多。

    普通的值类型数组比如int[],short[]什么的,这个都好说,COM里都有对应的类型(VTS_PI4 VTS_PI2),而且就算是在C#里也可以用Marshal来分配非托管数组然后传递到COM里去进行操作。但字符串数组不同,它每一项长度都不一样,这给传递带来了一些困难。所以今天主要就说说字符串数组的传递。


 

    在COM里数组传递要用到一个叫做SAFEARRAY的东东包装一下。但是如果直接用SAFEARRAY进行传递,那么到C#里面的参数类型是IntPtr,还是一个指针,这样就给数据的获取带来不便。后来发现数组传递之前还要用VARIANT这个数据结构把SAFEARRAY再次包装一下,这样数据传到C#里后参数类型是Object,只需要用String[]强转一下就OK了,十分方便。其实我这段描述百度百科里好像也说的挺明白的,可以参考一下:http://baike.baidu.com/view/1907445.htm

    我们可以这样理解,SAFEARRAY就是存放数据的数组,而VARIANT就是一个壳子,就好比C#里装箱的概念一样,把变量变成Object后传递起来会方便一些。说的够多了,下面直接用代码举例了。

    

    首先,如果数组是传入参数的话,调度声明中需要用VTS_VARIANT,函数原型声明中类型是VARIANT*;如果是返回值的话调度声明要用VT_VARIANT,函数原型声明类型是VARIANT(注意不是VARIANT*,和传入参数有点不同,否则到C#里参数类型不是Object而是IntPtr);然后主要说下数组的构造和包装。

    VARIANT AryWarp;

    VariantInit( &AryWarp );

    AryWarp.vt = VT_ARRAY | VT_BSTR;   // 指定壳子是用来包装数组的,并且是字符串数组,注意COM里面字符串就是BSTR,其实就是宽字符串


 

    SAFEARRAY* psa; 

    SAFEARRAYBOUND bounds = { 10, 0 }; 

    psa = SafeArrayCreate( VT_BSTR, 1, &bounds );   // 这里就是初始化一个长度为10的字符串数组


 

    然后声明一个字符串数组 BSTR* bstrArray; 并且用SafeArrayAccessData将psa与bstrArray进行绑定(不知道绑定这个词合适不合适,反正给我的感觉就是绑定),然后要做的就是对bstrArray[ i ]赋值了,赋值完毕后记得用SafeArrayUnaccessData解除绑定。

    最后一步就是包壳子了, AryWarp.parray = psa; 然后就可以把AryWarp return了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值