XLL+ Class Library (7.0)

ExcepExt Sample

Demonstrates a function extension, which catches a developer-defined exception

Overview

This sample add-in demonstrates how to use a function extension so that all generated functions contain code to catch and handle specific C++ exceptions.

Assume that you are creating XLL+ wrapper functions for a library of functions that may raise exceptions of type MyException. It becomes tedious to write code to catch these in every wrapper function, and convert the exception to an Excel error.

Tis sample project shows how to use an XLL+ function extension to define exception-handling code that will be injected into any XLL+ function that uses the extension.

We start with a global function that converts a caught exception into an Excel error string:

CopyC++
inline void ConvertException(const MyException& e, CXlOper& xloResult)
{
    xloResult = "#ERROR: " + e.getText();
}

Normally we would write code in our XLL+ implementation function to call this conversion function:

CopyC++
CXlOper* MySqrt1_Impl(CXlOper& xloResult, double x)
{
    // End of generated code 
//}}XLP_SRC 
    try
    {
        xloResult = CalcSquareRoot(x);
    }
    catch(const MyException& e)
    {
        ConvertException(e, xloResult);
    }
    return xloResult.Ret();
}

We can instead choose to inject code into the outer XLL+ functions (in this case MySqrt1_4 and MySqrt1_12) to trap the exception. This has the advantage of remiving the try...catch blocks from the implementation function.

CopyC++
CXlOper* MySqrt1_Impl(CXlOper& xloResult, double x)
{
    // End of generated code 
//}}XLP_SRC
    xloResult = CalcSquareRoot(x);
    return xloResult.Ret();
}

The code to be injected into the outer function needs to appear at the end of the exception handling section, as an additional catch statement, just after XLP_CATCH_CLR_EXCEPTIONS_TO(xloResult):

CopyC++
extern "C" __declspec(dllexport)
LPXLOPER12 MySqrt2_12(double x)
{
    XLL_FIX_STATE;
    CXlOper xloResult;
    try {
        CXlStructuredExceptionHandler _seh_;
        xloResult.HandleResult(MySqrt2_Impl(xloResult, x));
    }
    catch(const CXlRuntimeException& ex) {
        CXllApp::Instance()->DisplayException(xloResult, ex);
    }
    XLP_CATCH_CLR_EXCEPTIONS_TO(xloResult)
    catch(const MyException& e) {
        ConvertException(e, xloResult);
    }
    return xloResult.Ret12();
}

Requirements

To edit the functions in this add-in, you need to load the extension file MyException.xpe which is located in the sample directory. See Loading an extension file for instructions.

The function extension

The extension is in MyException.xpe. It contains 4 essential items:

  1. A reference to MyException.h, which ensures that the code will be included in any file that uses the extension.
  2. A LocalizedDisplayName element which controls how the extension will appear in the Property Browser.
  3. A LocalizedDescription element which provoides help in the Property Browser.
  4. An Insertion element, which species the code which will be inserted by the extension, and its location, in this case: AfterCatchException. (Note that the code is wrapped in a CDATA element, so that the ampersand character can be used in the inserted code without being escaped.)

Classes and functions used

CXlOper::operator =

Sample project

Each sample project is located in a sub-directory of the Samples directory of the XLL+ installation. To use the sample project, open the solution file ExcepExt.sln or the project file ExcepExt.vcproj.

You can enable debugging under Excel by using the Setup Debugging command in the XLL+ ToolWindow.

When delivered, the help files are excluded from the build. You can enable the help build by selecting the files ExcepExt.help.xml and ExcepExt.chm in the Solution Explorer, and using the right-click menu to view Properties. Select the page "Configuration Properties/General" and set the "Excluded from build" property to "No". See Generating help in the User Guide for more information.

See Also

List of Sample Projects | Function extensions (User Guide) | FunctionExtension element (Reference)