这几天,一直为一个以前没见过的类型头痛不已,网上找解决方法又不贴切,着实让我难受了一阵子.今天终于把问题解决,在这里跟大家分..
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);
}
}
尽供参考.