# What is the Matrix - Part 2 - VARIANT abstractions

this article was originally posted on CodeGuru in 2003 and has been copied here for archival purposes (and to fix some broken links and tidy up the code formatting) ## Introduction #

The Matrix is a small C++ utility class that is distributed in a single header file. It simplifies working with arrays. Source code and a small demo project in GitHub.

This is the second of three articles that explains how to use the different features of the Matrix. In the previous article, I described how to use the basic features of the Matrix. In this article, I will explain how to use the built-in conversions to and from `VARIANT`s.

I would first recommend reading the first article as it covers basic features.

## Converting to and from `VARIANT`#

The following code shows how to create a basic two-dimensional array

``CMatrix<long> matrix;matrix.cell(0,0)=100;matrix.cell(1,0)=200;matrix.cell(0,1)=300;matrix.cell(1,1)=400;``

The matrix now looks like this...

``100   200300   400``

Now, suppose you had a method in a COM object that wanted an array. The method looks like this...

``HRESULT SomeMethod(VARIANT vArray)``

To pass the Matrix to this method, simply pass the Matrix like so...

``HRESULT hr = SomeMethod(matrix);``

This works because the Matrix is implicitly converted to a `VARIANT` by its `operator VARIANT` function.

Now, let's look at the `SomeMethod` function and see how this can benefit from using the Matrix...

``HRESULT SomeMethod(VARIANT vArray){    CMatrix<_variant_t> matrix (vArray);    long theLong=(long)m.cell(1,0) ;    // should give us 200}``

Here, the array is passed in as a `VARIANT`. The `VARIANT` contains a `SAFEARRAY`. We construct a `Matrix` from the `VARIANT` that was passed in. The matrix looks like this...

``````100	200
300	400
``````

We now have an exact copy of the Matrix in our COM server object. Passing arrays back to the client is just as easy...

``HRESULT SomeMethod(VARIANT vArray, VARIANT* pvArray){  CMatrix<_variant_t> m (vArray ) ;   for ( ULONG l = 0 ; l < m.width( ) ; l++ )  {    long lNum (m.cell(l,0));    m.cell(l,0) = lNum * 2 ;  }   *pvArray = m ;}``

The code above, in just a few lines of code, takes a 2D `SAFEARRAY`, multiplies every number in the array by 2, and returns a new `SAFEARRAY`.

## Multilingual #

Let's say you've used the Matrix in your COM object. You needn't (nor shouldn't) restrict the clients of your object to be C++ clients. The following snippet of VB passes arrays to and from a COM object that uses the Matrix...

``Dim a As New Calculator Dim moreInts(0 To 9) As VariantDim looper As Integer For looper = 1 To 10  moreInts(looper - 1) = looperNext Dim arr As Variantarr = a.MultiplyItems(moreInts, 2) Dim s As String For looper = 0 To 9  s = s & arr(looper, 0) & ", "Next MsgBox s``

## The Examples #

The examples presented with this article constitute a COM Local Server object (Calculator) written in C++, a client application written in C++, and another client application written in VB.

This Server contains one object (`Calculator`) that has one method (`MultiplyItems`). This method takes three parameters: an input array, an output array, and a Factorial integer (the amount to multiply the numbers by). The C++ client simply fills an array with numbers and outputs the result from the MultiplyItems method on the server. The Visual Basic client does the same thing. One thing to note in the VB examples is that the arrays are 0 based (rather than 1 based).

## Conclusion #

Hopefully, this article has shown you how to use the Matrix to create and pass arrays. Please feel free to leave comments and feedback. In my next article, I will explain how to use stream operators with the Matrix.