XLL+ Class Library (7.0)

Using matrix data

Code generated by the wizard

Whens you return to Visual Studio, you will see that the wizard has inserted the source code for the new function at the end of your C++ file. The interesting part is shown below.

CopyC++
CXlOper* INTERP2D_Impl(CXlOper& xloResult, const CXlOper* X_op, const CXlOper* 
    Y_op, const CXlOper* Z_op, double InterpX, double InterpY)
{
    // Input buffers 
    std::vector<double> X;
    std::vector<double> Y;
    ple::mtx_ptrs<double> Z;
    // Validate and translate inputs
    XlReadVector(*X_op, X, L"X", XLA_TRUNC_ONEMPTY|XLA_TRUNC_ONBLANK);
    XlReadVector(*Y_op, Y, L"Y", XLA_TRUNC_ONEMPTY|XLA_TRUNC_ONBLANK);
    XlReadMatrix(*Z_op, mtx_adapter(Z), L"Z", XLA_TRUNC_ONEMPTY|
        XLA_TRUNC_ONBLANK);                                     
    // End of generated code 
//}}XLP_SRC 
    // TODO - set the value of xloResult, or return another value 
    //          using CXlOper::RetXXX() or throw a CXlRuntimeException. 
    return xloResult.Ret();
}

Most of this code is pretty familiar stuff. Let's examine the new code for handling the matrix.

CopyC++
ple::mtx_ptrs<double> Z;
XlReadMatrix(*Z_op, mtx_adapter(Z), L"Z", XLA_TRUNC_ONEMPTY|
    XLA_TRUNC_ONBLANK);

As you may remember, our implementation function, LinearInterp2D(), expects the matrix argument to be passed as an array of pointers to one-dimensional arrays of doubles, where each of the arrays of doubles represents one column of data.

The wizard has generated code that does a number of useful things:

  1. Declares a matrix variable, Z, which will hold the data extracted from the COper. For reasons of efficiency, the matrix is of type mtx_ptrs<T>.
  2. Calls the XlReadMatrix() method, which extracts the values from the CXlOper Z_op, and populates Z. If any of the data in Z is unacceptable, XlReadMatrix() throws an exception.

So, at the end of the Wizard-generated code, we have exactly what we need to call LinearInterp2D():

Add your own code

The code we add to the wizard-generated skeleton needs to do two things:

  1. Call LinearInterp2D().
  2. Return either an error code or the calculated result.

Generally, this is all an add-in function does. Most of the time, most of the code is generated by the wizard.

Add the code shown below, which calls LinearInterp2D().

CopyC++
CXlOper* INTERP2D_Impl(CXlOper& xloResult, const CXlOper* X_op, const CXlOper* 
    Y_op, const CXlOper* Z_op, double InterpX, double InterpY)
{
    ...
//}}XLP_SRC 
 
    double dInterpZ;                                                     
    if (LinearInterp2D((int)X.size(), &X[0], (int)Y.size(), &Y[0], &Z[0],
                       InterpX, InterpY, &dInterpZ))                     
        xloResult = dInterpZ;                                            
    else                                                                 
        xloResult = xlerrNum;                                            
 
    return xloResult.Ret();
}

Next: Constraining array sizes >>