Whens you return to Visual Studio, you will see that the wizard will has inserted the source code for the new function at the end of your C++ file. The interesting part is shown below.
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.
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:
So, at the end of the Wizard-generated code, we have exactly what we need to call LinearInterp2D():
The code we add to the wizard-generated skeleton needs to do two things:
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().
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(X.size(), &X[0], Y.size(), &Y[0], &Z[0], InterpX, InterpY, &dInterpZ)) xloResult = dInterpZ; else xloResult = xlerrNum; return xloResult.Ret(); }