Taking the Complexity Out of Creating COM Arrays’�The Matrix Class Utility

Environment: Visual Studio 6 with latest service pack, Visual Studio .NET

What Is Matrix?

Matrix is a templatised utility class with many uses. One of it best features is it takes away the complexity of creating COM arrays (SAFEARRAYS). Matrix was initially designed as a 2D array helper class. It later became far more useful when changed to a template class to store different types. A Matrix object can be treated as if it were a VARIANT data type. Anything that can be stored in a VARIANT, including arrays, can be stored in a Matrix. Anything you previously marshalled between apartment/process/machine boundaries can use Matrix.

I will begin describing Matrix in its simplest form and then progressing to more advanced and useful features.

What Can Be Stored in a Matrix?

In its simplest form, the Matrix can be used like so:

matrixLong ;
matrixLong.cell(1,1)=111 ;
matrixLong.cell(2,2)=222 ;

printf("Contents of cell 1,1 is %d and cell 2,2 is %d",

This outputs:

Contents of cell 1,1 is 111 and cell 2,2 is 222

Another example uses a user-defined object:

class CMyObject
    long  m_lNumber ;

            CMyObject( long l ) { m_lNumber = l; }
            long getNumber( )const { return m_lNumber; }

CMatrix<CMyObject*> m ;
for ( int i = 0 ; i < 100 ; i++ )
    m.cell(i,0)=new CMyObject( i*2 ) ;

// The Matrix above now contains 100 pointers to CMyObject objects.
// Each cell can now be treated as if it's a CMyObject pointer.
// For example:
long    l = m.cell(5,0)->getNumber( );
printf("Contents of cell 5,5 is %dn", l ) ;

The example above creates a Matrix and fills it with CMyObjects. It then retrieves a cell at position 5,0. This cell contains a .CMyObject* (or whatever else in specified in the template declaration).

What Else Does Matrix Do?

One of the most interesting features of Matrix is it’s ability to hide the details of creating and using SAFEARRAYs. The following example creates a two-dimensional array and passes it to a function in a VARIANT form. The function then creates a Matrix from the VARIANT.

// The function below expects a VARIANT. Since VARIANTS are
// marshaled automatically, the function below can be in a
// different project or module, or even on a different machine
void giveMeAVariant(VARIANT v )
  CMatrix<_variant_t> t(v);
  printf("matrix is %d wide & %d highn", t.width( ),
                                          t.height( ) ) ;
  printf("Contents of cell 5,5 is %d", (long)t.cell(5,5) ) ;

CMatrix<_variant_t> m;
for ( long i = 0 ; i < 100 ; i++ )

giveMeAVariant( m ) ;

This outputs:

matrix is 100 wide & 100 high
Contents of cell 5,5 is 5

In this example, we have created a SAFEARRAY packaged in a VARIANT in 3 lines of code. Remember, the function .giveMeAVariant. can be in a different apartment, module, application, or even machine. Hopefully, you can see that this utility class is very useful in hiding the complexities of SAFEARRAYs as well as handling two-dimensional arrays easily.

How Do I Integrate It with My Existing Code?

The complete implementation of Matrix is surprisingly small. It is self-contained within 1 header file (matrix.h). To include the file in your project, ensure the path where you store the file is in your path look-up settings for your project. Then, simply include the header file wherever you want to use a Matrix class. Because it is simply a header file, it will inherit whatever project settings you have specified, such as warning level and UNICODE setting.

With What Compilers/Tools Can I Use It?

Because Matrix is a simple header file, it can (in theory, I haven’t tried it) be used with any compiler that supports templates. I have used Matrix on Visual Studio 6 and Visual Studio .Net.


There are many features in Matrix that make it a valuable aid in your day-to-day programming. In the near future, I will provide more examples of how to use this powerful class.


Download demo applications – 167 Kb

Download demo source – 54 Kb

Download header file – 17 Kb

More by Author

Must Read