xlAutoFree/xlAutoFree12

Gilt für: Excel 2013 | Office 2013 | Visual Studio

Wird von Microsoft Excel aufgerufen, nachdem eine XLL-Arbeitsblattfunktion eine XLOPER-XLOPER12/ mit einem Flag zurückgibt, das ihr mitteilt, dass arbeitsspeicher vorhanden ist, den die XLL noch freigeben muss. Dadurch kann die XLL dynamisch zugewiesene Arrays, Zeichenfolgen und externe Verweise auf das Arbeitsblatt ohne Speicherverluste zurückgeben. Weitere Informationen finden Sie unter Speicherverwaltung in Excel.

Ab Excel 2007 werden die xlAutoFree12-Funktion und der datentyp XLOPER12 unterstützt.

Excel erfordert keine XLL, um eine dieser Funktionen zu implementieren und zu exportieren. Sie müssen dies jedoch tun, wenn Ihre XLL-Funktionen eine XLOPER- oder XLOPER12 zurückgeben, die dynamisch zugeordnet wurde oder Zeiger auf dynamisch zugewiesenen Speicher enthält. Stellen Sie sicher, dass Ihre Wahl zur Verwaltung des Arbeitsspeichers für diese Typen in Ihrer gesamten XLL und mit der Implementierung von xlAutoFree und xlAutoFree12 konsistent ist.

In der xlAutoFreexlAutoFree12-Funktion/ sind Rückrufe in Excel deaktiviert, mit einer Ausnahme: xlFree kann aufgerufen werden, um excel-zugewiesenen Arbeitsspeicher freizugeben.

void WINAPI xlAutoFree(LPXLOPER pxFree);
void WINAPI xlAutoFree12(LPXLOPER12 pxFree);

Parameter

pxFree (LPXLOPER im Fall von xlAutoFree)

pxFree (LPXLOPER12 im Fall von xlAutoFree12)

Ein Zeiger auf die XLOPER oder die XLOPER12 , die über Arbeitsspeicher verfügt, der freigegeben werden muss.

Eigenschaftswert/Rückgabewert

Diese Funktion gibt keinen Wert zurück und sollte als "void" deklariert werden.

Hinweise

Wenn Excel für die Neuberechnung von Multithreadarbeitsmappen konfiguriert ist, wird xlAutoFreexlAutoFree/ für denselben Thread aufgerufen, der zum Aufrufen der Funktion verwendet wird, die sie zurückgegeben hat. Der Aufruf von xlAutoFree/ xlAutoFree12 erfolgt immer vor der Auswertung aller nachfolgenden Arbeitsblattzellen in diesem Thread. Dies vereinfacht das threadsichere Design in Ihrer XLL.

Wenn die von Ihnen bereitgestellte xlAutoFreexlAutoFree12-Funktion/ das xltype-Feld von pxFree betrachtet, denken Sie daran, dass das xlbitDLLFree-Bit weiterhin festgelegt wird.

Beispiel

Beispielimplementierung 1

Der erste Code von \SAMPLES\EXAMPLE\EXAMPLE.C veranschaulicht eine sehr spezifische Implementierung von xlAutoFree, die nur mit einer Funktion, fArray, funktioniert. Im Allgemeinen verfügt Ihre XLL über mehr als nur eine Funktion, die Arbeitsspeicher zurückgibt, der freigegeben werden muss. In diesem Fall ist eine weniger eingeschränkte Implementierung erforderlich.

Beispielimplementierung 2

Die zweite Beispielimplementierung entspricht den Annahmen, die in den XLOPER12-Erstellungsbeispielen in Abschnitt 1.6.3, xl12_Str_example, xl12_Ref_example und xl12_Multi_example verwendet werden. Es wird davon ausgegangen, dass beim Festlegen des xlbitDLLFree-Bits alle Zeichenfolgen, Arrays und externen Referenzspeicher dynamisch mithilfe von malloc zugeordnet wurden und daher in einem Aufruf von free freigegeben werden müssen.

Beispielimplementierung 3

Die dritte Beispielimplementierung ist konsistent mit einer XLL, bei der exportierte Funktionen, die XLOPER12zurückgeben, Zeichenfolgen, externe Verweise und Arrays mithilfe von malloc zuordnen und bei denen die XLOPER12 selbst ebenfalls dynamisch zugeordnet wird. Das Zurückgeben eines Zeigers auf eine dynamisch zugeordnete XLOPER12 ist eine Möglichkeit, um sicherzustellen, dass die Funktion threadsicher ist.

//////////////////////////////////////////
//       BEGIN EXAMPLE IMPLEMENTATION 1
//////////////////////////////////////////
LPXLOPER12 WINAPI fArray(void)
{
    LPXLOPER12 pxArray;
    static XLOPER12 xMulti;
    int i;
    int rwcol;
    xMulti.xltype = xltypeMulti | xlbitDLLFree;
    xMulti.val.array.columns = 1;
    xMulti.val.array.rows = 8;
    // For large values of rows and columns, this would overflow
    // use __int64 in that case and return an error if rwcol
    // contains a number that won't fit in sizeof(int) bytes
    rwcol = xMulti.val.array.columns * xMulti.val.array.rows; 
    pxArray = (LPXLOPER12)GlobalLock(hArray = GlobalAlloc(GMEM_ZEROINIT, rwcol * sizeof(XLOPER12)));
    xMulti.val.array.lparray = pxArray;
    for(i = 0; i < rwcol; i++) 
    {
        pxArray[i].xltype = xltypeInt;
        pxArray[i].val.w = i;
    }
// Word of caution - returning static XLOPERs/XLOPER12s is not thread safe
// for UDFs declared as thread safe, use alternate memory allocation mechanisms
    return (LPXLOPER12)&xMulti;
}
void WINAPI xlAutoFree12(LPXLOPER12 pxFree)
{
    GlobalUnlock(hArray);
    GlobalFree(hArray);
    return;
}
//////////////////////////////////////////
//       BEGIN EXAMPLE IMPLEMENTATION 2
//////////////////////////////////////////
void WINAPI xlAutoFree12(LPXLOPER12 pxFree)
{
    if(pxFree->xltype & xltypeMulti)
    {
/* Assume all string elements were allocated using malloc, and
** need to be freed using free.  Then free the array itself.
*/
        int size = pxFree->val.array.rows *
            pxFree->val.array.columns;
        LPXLOPER12 p = pxFree->val.array.lparray;
        for(; size-- > 0; p++) // check elements for strings
            if(p->xltype == xltypeStr)
                free(p->val.str);
        free(pxFree->val.array.lparray);
    }
    else if(pxFree->xltype & xltypeStr)
    {
        free(pxFree->val.str);
    }
    else if(pxFree->xltype & xltypeRef)
    {
        free(pxFree->val.mref.lpmref);
    }
}
//////////////////////////////////////////
//       BEGIN EXAMPLE IMPLEMENTATION 3
//////////////////////////////////////////
LPXLOPER12 WINAPI example_xll_function(LPXLOPER12 pxArg)
{
// Thread-safe return value. Every invocation of this function
// gets its own piece of memory.
    LPXLOPER12 pxRtnValue = (LPXLOPER12)malloc(sizeof(XLOPER12));
// Initialize to a safe default
    pxRtnValue->xltype = xltypeNil;
// Set the value of pxRtnValue making sure that strings, external
// references, arrays, and strings within arrays are all dynamically
// allocated using malloc.
//    (code omitted)
//    ...
// Set xlbitDLLFree regardless of the type of the return value to
// ensure xlAutoFree12 is called and pxRtnValue is freed.
    pxRtnValue->xltype |= xlbitDLLFree;
    return pxRtnValue;
}
void WINAPI xlAutoFree12(LPXLOPER pxFree)
{
    if(pxFree->xltype & xltypeMulti)
    {
// Assume all string elements were allocated using malloc, and
// need to be freed using free. Then free the array itself.
        int size = pxFree->val.array.rows *
            pxFree->val.array.columns;
        LPXLOPER12 p = pxFree->val.array.lparray;
        for(; size-- > 0; p++) // check elements for strings
            if(p->xltype == xltypeStr)
                free(p->val.str);
        free(pxFree->val.array.lparray);
    }
    else if(pxFree->xltype & xltypeStr)
    {
        free(pxFree->val.str);
    }
    else if(pxFree->xltype & xltypeRef)
    {
        free(pxFree->val.mref.lpmref);
    }
// Assume pxFree was itself dynamically allocated using malloc.
    free(pxFree);
}

Siehe auch

Add-In-Manager und XLL-Benutzeroberflächenfunktionen