xlAutoFree/xlAutoFree12

Aplica-se a: Excel 2013 | Office 2013 | Visual Studio

Chamado pelo Microsoft Excel logo após uma função de planilha XLL retornar umXLOPER12XLOPER/ para ele com um conjunto de sinalizadores que informa que há memória de que a XLL ainda precisa ser lançada. Isso permite que a XLL retorne matrizes, cadeias de caracteres e referências externas dinamicamente alocadas para a planilha sem vazamentos de memória. Saiba mais em Gerenciamento de Memória no Excel.

A partir do Excel 2007, há suporte para a função xlAutoFree12 e o tipo de dados XLOPER12 .

O Excel não requer uma XLL para implementar e exportar nenhuma dessas funções. No entanto, você deve fazer isso se suas funções XLL retornarem um XLOPER ou XLOPER12 que tenha sido alocado dinamicamente ou que contenha ponteiros para memória alocada dinamicamente. Verifique se a escolha de como gerenciar a memória para esses tipos é consistente em toda a XLL e com a forma como você implementou xlAutoFree e xlAutoFree12.

Dentro da função xlAutoFree/ xlAutoFree12 , os retornos de chamada no Excel estão desabilitados, com uma exceção: xlFree pode ser chamado para liberar memória alocada pelo Excel.

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

Parâmetros

pxFree (LPXLOPER no caso de xlAutoFree)

pxFree (LPXLOPER12 no caso de xlAutoFree12)

Um ponteiro para o XLOPER ou o XLOPER12 que tem memória que precisa ser liberada.

Valor de propriedade/Valor de retorno

Essa função não retorna um valor e deve ser declarada como nulo de retorno.

Comentários

Quando o Excel é configurado para usar o recalculação de pasta de trabalho multithread, xlAutoFree/ xlAutoFree12 é chamado no mesmo thread usado para chamar a função que a retornou. A chamada para xlAutoFree/ xlAutoFree12 é sempre feita antes que as células subseqüentes da planilha sejam avaliadas nesse encadeamento. Isso simplifica o design seguro para thread em sua XLL.

Se a função xlAutoFree/ xlAutoFree12 que você fornece examinar o campo xltype do pxFree, lembre-se de que o bit xlbitDLLFree ainda será definido.

Exemplo

Implementação de exemplo 1

O primeiro código de \SAMPLES\EXAMPLE\EXAMPLE.C demonstra uma implementação muito específica do xlAutoFree, que foi projetado para funcionar com apenas uma função, fArray. Em geral, sua XLL terá mais de uma função retornando memória que precisa ser liberada, nesse caso, uma implementação menos restrita é necessária.

Implementação de exemplo 2

A implementação do segundo exemplo é consistente com as suposições usadas nos exemplos de criação XLOPER12 na seção 1.6.3, xl12_Str_example, xl12_Ref_example e xl12_Multi_example. As suposições são de que, quando o bit xlbitDLLFree foi definido, toda a cadeia de caracteres, matriz e memória de referência externa foi alocada dinamicamente usando malloc e, portanto, precisa ser liberada em uma chamada gratuita.

Implementação de exemplo 3

A implementação do terceiro exemplo é consistente com uma XLL em que funções exportadas que retornam cadeiasde caracteres alocadas XLOPER12, referências externas e matrizes usando malloc e onde o XLOPER12 em si também é alocado dinamicamente. Retornar um ponteiro para um XLOPER12 alocado dinamicamente é uma maneira de garantir que a função seja segura por thread.

//////////////////////////////////////////
//       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);
}

Confira também

Gerenciador de Suplemento e Funções da Interface XLL