SafeArray Template Class
For your convenience, SolidWorks created a SafeArray template class to use to
instantiate SafeArrays for SolidWorks methods requiring VARIANT arrays. The code
for the SafeArray template class is as follows:
/This class manages the VARIANT SafeArrays that many SolidWorks API methods return
#define ASSERT _ASSERT
#pragma once
#include "stdafx.h"
template <class T,int type> class SafeArray
{
public:
SafeArray(VARIANT *input):
m_input(input),
m_access(false),
m_bCreate(false),
m_pSafeArray(NULL),
m_arrayData(NULL),
m_result(S_OK)
{
if(m_input != NULL)
{
if (V_VT(m_input) != VT_EMPTY)
{
m_pSafeArray = V_ARRAY (m_input);
m_result = SafeArrayAccessData ( m_pSafeArray, (void HUGEP**)&m_arrayData);
m_access = m_result == S_OK ;
}
else
m_access = true;
}
else
{
ASSERT(FALSE);
m_input = &m_target;
}
}
SafeArray(const VARIANT &input) :
m_access(true),
m_bCreate(false),
m_pSafeArray(NULL),
m_arrayData(NULL),
m_result(S_OK)
{
m_input = (VARIANT *) &input;
if (V_VT(m_input) != VT_EMPTY)
{
m_pSafeArray = V_ARRAY (m_input);
m_result = SafeArrayAccessData ( m_pSafeArray, (void HUGEP**)&m_arrayData);
m_access = m_result == S_OK ;
}
else
m_access = true;
}
SafeArray(unsigned int size,unsigned int dims = 1):
m_input(&m_target),
m_access(false),
m_bCreate(true),
m_pSafeArray(NULL),
m_arrayData(NULL),
m_result(S_OK)
{
ASSERT(size >= 0);
if(size > 0)
{
m_rgsabound[0].lLbound = 0;
m_rgsabound[0].cElements = (int) size;
m_pSafeArray = SafeArrayCreate(type, (int)dims, m_rgsabound);
V_VT(m_input) = VT_ARRAY | type;
m_result = SafeArrayAccessData( m_pSafeArray, (void HUGEP**)&m_arrayData);
m_access = m_result == S_OK ;
if(!m_access)
V_VT(m_input) = VT_EMPTY;
}
else
{
V_VT(m_input) = VT_EMPTY;
m_access = true;
}
}
inline HRESULT status(){return m_result;}
inline int getSize(int index = 0) {return (m_access&&m_pSafeArray)?m_pSafeArray->rgsabound[index].cElements:0;}
~SafeArray(){UnaccessData();}
operator T* () {ASSERT(m_access);return m_arrayData;}
operator VARIANT () {ASSERT(m_access); return *m_input;}
T & operator[](int i) {ASSERT(m_access&&m_arrayData);return m_arrayData[i];}
private:
void UnaccessData(){
if(m_access){
m_result = SafeArrayUnaccessData( m_pSafeArray );
if(m_bCreate && m_result == S_OK)
V_ARRAY(m_input) = m_pSafeArray;
m_access = false;
}
}
bool m_bCreate;
bool m_access;
VARIANT *m_input;
VARIANT m_target;
T *m_arrayData ;
SAFEARRAY *m_pSafeArray;
SAFEARRAYBOUND m_rgsabound[1];
HRESULT m_result;
};
//common array types
typedef SafeArray<VARIANT_BOOL, VT_BOOL> SafeBooleanArray;
typedef SafeArray<double, VT_R8> SafeDoubleArray ;
typedef SafeArray<long, VT_I4> SafeLongArray ;
typedef SafeArray<BSTR, VT_BSTR> SafeBSTRArray ;
typedef SafeArray<LPDISPATCH, VT_DISPATCH> SafeDISPATCHArray;
typedef SafeArray<LPVARIANT, VT_VARIANT> SafeVARIANTArray;