XLL+ Class Library

Further enhancements

There are many enhancements you may choose to add to the model. Some of the most obvious are discussed below.

Multiple results

If a function returns multiple results, you should have a single add-in function for each distinct result; the functions will vary only in that they will extract different output data members from the data object.

Persistent cache

The cache could be saved to disk whenever the add-in is closed - i.e. during OnXllClose(). One might choose to stream it to a binary file, or more usefully, store it in a database.

When designing the serialization mechanism, it is worth remembering that there may be multiple instances of Excel open, each of them with a separate in-memory cache. Thus, when saving the in-memory cache, it is advisable to perform the following steps as a single atomic operation.

  1. Lock the persistent cache file.
  2. Read the cache file into memory.
  3. Add any records from the in-memory cache built by this add-in.
  4. Save the merged cache to disk.

Multiple caches

If you have multiple functions in a single add-in which you wish to run asynchronously, you should have multiple caches in a single add-in. Each cache should use a different named channel. For example, if the new function BarrierOptValue() was added to the add-in, it would use a new data object class, e.g. BarrierOptData, a new cache class BarrierOptDataCache and an instance of BarrierOptDataCache in the application class CAvgOptApp.

Most important, when the worker thread for the BarrierOptData object completed, it should use a different channel to inform RTD of its completion, e.g.:

void __stdcall BarrierOptValue_threadfn(void* pvData)
{
    BarrierOptData* args = (BarrierOptData*)pvData;

    args->Evaluate();
    args->done = true;
    psl::XllRtdSharedData::IncrementChannelSeqNum("BarrierOpt");
}

In addition, the cell containing the sequence number passed to BarrierOptValue() should contain the appropriate channel name, e.g.:

=RTD("XllRtdLink.XllRtdSeqNumServer",,"BarrierOpt")

This pattern will keep updates of the two functions separate from each other.

Next: COM server module: XllRtdLink >>