Multiple Instances of Microsoft Excel

Windows 16-Bit Only

You must consider the possibility that your DLL will be called by more than one running instance of Microsoft Excel. If this happens, remember that your DLL has only one global data segment. For example, consider this code:

int i = 0;

int WINAPI test(void)
{
    return ++i;
}

This returns successive integers as long as there is only one copy of Microsoft Excel using this DLL. But if there are multiple instances of Microsoft Excel running at the same time and intermittently calling this DLL, there will still be only one copy of the variable i between all the instances. This means that your DLL cannot save state as easily as a normal C program can. What can you do about this, if you need a DLL to maintain a state that is distinct for each instance of Microsoft Excel?

The usual solution is to use a block of memory called an instance block. For example, you have a program Zoo with two functions: see_bears and see_fish. You can create an initialization function init_zoo, which allocates an instance block of memory (using LocalAlloc or GlobalAlloc) that contains all of the state that is instance-specific. The function init_zoo returns a pointer (or handle) to this memory. Then see_bears and see_fish take this handle as the first argument. Finally, exit_zoo frees the global memory. The code might look like this:

typedef struct tagInstanceBlock
{
    int a;
    int b;
} INSTANCEBLOCK;

HANDLE WINAPI init_zoo()
{
    return GlobalAlloc(GMEM_MOVEABLE, sizeof(INSTANCEBLOCK));
}

void WINAPI see_bears(HANDLE hInstBlock)
{
    INSTANCEBLOCK FAR *pib;

    pib = GlobalLock(hInstBlock);

    // Now use pib->a and pib->b as instance-specific
    // variables

    GlobalUnlock(hInstBlock);
}

void WINAPI exit_zoo(HANDLE hInstBlock)
{
    GlobalFree(hInstBlock);
}

There are other ways around this problem. For example, you can store all instance-specific information on sheets, using Microsoft Excel to maintain your state. You can also store the instance handle in a name on the sheet or in the hidden name space. Or you can simply prevent multiple instances of Microsoft Excel from using your DLL. You can call the xlGetInst function to find out the instance handle of the instance that is calling you, so that you can distinguish between different instances.