XLL+ Class Library (7.0)

Sharing object handles between XLLs

Shared handles

Beginning with XLL+ version 7.0.6, it is possible to shared object handles between XLLs. An object can be constructed in one XLL, and its handle can be passed to a function in a second XLL for use within an add-in function.

For a class to be shared between XLLs, a number of conditions must be satisified.

  1. The handle provider XLL must export the function exported_GetCacheInstance().
  2. Each object type to be used in a Consumer XLL must be registered, by calling HandleCacheInstanceImportManager::RegisterType().
  3. The objects must be identically laid out in memory in both XLLs. Therefore both XLLs must use the identical compile and link flags.
  4. The compiler settings must be changed to use the shared DLL version of the Microsoft run-time libraries.
  5. The handle type must be set to one of the non-RTD handle types: StringHandle, StringPtrHandle or NumericHandle. The current implementation does not support sharing RTD handles.

Handle provider

A handle provider XLL that needs to share handles with other XLLs must export the function exported_GetCacheInstance().

This function may only be included by one C++ source file in any particular XLL. For one cpp file, and only one cpp file, insert #define NONRTDHANDLES_IMPLEMENT_EXPORT before the line that includes the handles extension file, e.g.

CopyC++
#define NONRTDHANDLES_IMPLEMENT_EXPORT
#include "extensions\StringHandles.h"

Including this line will have the effect that the function exported_GetCacheInstance() is created and exported.

If the line is not included by any CPP source file, then handles will not be exported for use by other XLLs.

Handle consumer XLLs

An XLL that uses handles created by another XLL - a consumer XLL - must instruct the global singleton instance of the HandleCacheInstanceImportManager object where to find handles of each type, by calling HandleCacheInstanceImportManager::RegisterType() during OnXllOpenEx(), e.g.:

CopyC++
BOOL CHandleConsumerApp::OnXllOpenEx()
{
    // Inform the controller that handles for the following object types will  
    // be sourced from "HandleProvider.xll"
    psl::HandleCacheInstanceImportManager::RegisterType(L"Thing", _T("HandleProvider.xll"));
    psl::HandleCacheInstanceImportManager::RegisterType(L"test::Thing2", _T("HandleProvider.xll"));
    psl::HandleCacheInstanceImportManager::RegisterType(L"std::map<std::string,std::string>", _T("HandleProvider.xll"));
    return TRUE;
}

The class name argument must be a wide (Unicode) string and must exactly match the form of the class name used in add-in functions. If a namespace is used in the add-in function's definition then the namespace must be used in the RegisterType() call.

Similarly, if template arguments are used, they must be in exactly the same form as in the add-in function, including white-space.

Note that the XLL name is in standard text form (either ASCII or Unicode depending on the project settings) and that it:

  1. includes the extension ".xll";
  2. does not include the directory of the XLL.

Example

For more details see the SharedHandles sample project.

Next: Grouping arguments >>