关于VC从VARIANT类型取数据的小结

    这几天,一直为一个以前没见过的类型头痛不已,网上找解决方法又不贴切,着实让我难受了一阵子.今天终于把问题解决,在这里跟大家分..

    VARIANT,变体类型,在VB中是一个可以容纳很多常用类型的超级类型,所以,如果不知道它的里面到底存了些什么数据,对着它就像对着一个从未见过面的朋友一样,不知该怎么交流.在这种情况下,我们可以通过取得VARIANT类型变量的vt值,得以确认:
      enum VARENUM
    { VT_EMPTY = 0,
 VT_NULL = 1,
 VT_I2 = 2,
 VT_I4 = 3,
 VT_R4 = 4,
 VT_R8 = 5,
 VT_CY = 6,
 VT_DATE = 7,
 VT_BSTR = 8,
 VT_DISPATCH = 9,
 VT_ERROR = 10,
 VT_BOOL = 11,
 VT_VARIANT = 12,
 VT_UNKNOWN = 13,
 VT_DECIMAL = 14,
 VT_I1 = 16,
 VT_UI1 = 17,
 VT_UI2 = 18,
 VT_UI4 = 19,
 VT_I8 = 20,
 VT_UI8 = 21,
 VT_INT = 22,
 VT_UINT = 23,
 VT_VOID = 24,
 VT_HRESULT = 25,
 VT_PTR = 26,
 VT_SAFEARRAY = 27,
 VT_CARRAY = 28,
 VT_USERDEFINED = 29,
 VT_LPSTR = 30,
 VT_LPWSTR = 31,
 VT_RECORD = 36,
 VT_FILETIME = 64,
 VT_BLOB = 65,
 VT_STREAM = 66,
 VT_STORAGE = 67,
 VT_STREAMED_OBJECT = 68,
 VT_STORED_OBJECT = 69,
 VT_BLOB_OBJECT = 70,
 VT_CF = 71,
 VT_CLSID = 72,
 VT_BSTR_BLOB = 0xfff,
 VT_VECTOR = 0x1000,
 VT_ARRAY = 0x2000,
 VT_BYREF = 0x4000,
 VT_RESERVED = 0x8000,
 VT_ILLEGAL = 0xffff,
 VT_ILLEGALMASKED = 0xfff,
 VT_TYPEMASK = 0xfff
    };

    这个枚举结构里,存着vt值的宏定义,假如m_DataA为VARIANT类型变量,m_DataA .vt = 4,则这个变量里的就是存的一个单精度数据(以上宏在MSDN均可查到所代表的类型),当然,上面的宏可以叠加使用,比如说m_DataA.vt =  8204,转化成十六进制数为0x200C,VT_ARRAY = 0x2000,VT_VARIANT = 12(12的十六进制为:C),变量里存的数据是一个 变体数组类型(VT_ARRAY |VT_VARIANT ).

 

SafeArray是VB中的数组存储方式。通过SafeArray,可以在VC++和VB间相互调用。

 

 

SafeArrayGetLBound(SAFEARRAY * psa, UINT nDim, LONG * plLbound);

SafeArrayGetUBound(SAFEARRAY * psa, UINT nDim, LONG * plUbound);
假如变量里存的是数组数据,这两个API函数是用来得到该数组下标的起始和结束位置.

 

 

SafeArrayAccessData(SAFEARRAY * psa, void HUGEP** ppvData);

     这个函数用于获取SafeArray的数据指针,并锁定SafeArray数组的数据。在取得了数据指针之后,就可以直接访问SafeArray数组中的数据了。

     如果数组类型是Type,那么所取得的数据指针实际上就是Type类型的数组的地址。在多维数组的情况下,必须把多个维度的下标转换成一维下标进行访问。

 

 

SafeArrayUnaccessData(SAFEARRAY * psa);

这个函数的作用是对SafeArray数据解锁,解锁后,就不应该继续对数据指针进行读写访问。如果要访问,必须重新获取并锁定数据。

 

 

示例:

VARIANT INMR::GetDataA()
{
 VARIANT result;
 InvokeHelper(0x1a, DISPATCH_PROPERTYGET, VT_VARIANT, (void*)&result, NULL);
 return result;
}

 

void CNMR02View::GetNMRDataA()
{
 VARIANT m_nVarA = iRiNMR.GetDataA();
 
 if(m_nVarA.vt = VT_ARRAY|VT_VARIANT)
 {
  long upBoundA,lowBoundA;
  SAFEARRAY *pDataA = m_nVarA.parray;
  SafeArrayGetUBound(pDataA,1,&upBoundA);
  SafeArrayGetLBound(pDataA,1,&lowBoundA);
  VARIANT *pTmp = 0;
  SafeArrayAccessData(pDataA,(void**)&pTmp);
  for(int i = lowBoundA; i < upBoundA ; i++)
  {
   m_DataA.push_back(pTmp[i].dblVal);
  
  
  }
  SafeArrayUnaccessData(pDataA);
  SafeArrayDestroy(pDataA);
 }
 

}

 

尽供参考.

 

 

 

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值