XLL+ Class Library (7.0)

Function extensions

You may have some standard code that you use in most or all of your add-in functions. You can transfer responsibility for writing the code to the XLL+ code generator by writing and registering a Function extension.

Typical uses of function extensions include:

Behavior of a function extension

When a function extension is registered, it appears in the XLL+ Function Wizard and in the Properties window, as an option that can be applied to any add-in function.

For example, if we register an extension named Trace, which writes to the debug console every time a function is used, we can see it in the function's Features list.

If we put a check against it, then additional lines will be injected into the generated code:

CXlOper* StringFn_Impl(CXlOper& xloResult, const CXlStringArg& Product_op)
    TRACE(_T("Entering StringFn\n")); 
    // Input buffers
    CString Product;
    // Validate and translate inputs
    XlReadScalarEx(Product_op, Product, psl::FixedLengthStringConverter(), 
        CScalarConvertParams<CString>(L"Product", 0, 0, -1).SetIntParam(0, 4));
    TRACE(_T("Validated StringFn\n")); 
  // End of trace 
    // End of generated code 

If at a later time you want to remove the extra code, you can use the Function Wizard or the Properties window to turn the extension off.

Code injection

Extension code can be injected at various places in an add-in function.

Insertion point Description
BeforeValidation At the start of the common implementation function, before any validation code is called.
AfterValidation In the common implementation function, immediately after all validation code has been called.
BeforeTryCatch At the start of each wrapper function before the try-catch block that calls the common implementation function.
AfterCatchException In each wrapper function, after the try-catch block that calls the common implementation function. (This is a good place to catch exceptions that are not derived from CXlRuntimeException.)
BeforeMacro Outside any function definition, in a global context, just before the IMPLEMENT_XLLFN3 macro.
AfterMacro Outside any function definition, in a global context, just after the IMPLEMENT_XLLFN3 macro, and before the wrapper functions.

In the example above, TRACE statements were injected at BeforeValidation and AfterValidation.


The full syntax of function extensions can be found in the reference here.

The critical part of the extension's definition is the code that is to be injected. You can use macros that will be substituted by the code generation engine, and allow you to generate data that is specific to the add-in function being extended.

For example, the Trace extension above uses the add-in function's name:

TRACE(_T("Entering $#ExportedName$\n"));

The generator will replace $#ExportedName$ with the value of the add-in function's ExportedName property.

You can find a list of function properties in the reference.


See the Profiling sample for an example of a function extension in action.

For more examples of function extensions see the files in the extensions directory.

Next: The need for object handles >>

See Also

Profiling sample