xlAutoFree/xlAutoFree12
Hace referencia a: Excel 2013 | Office 2013 | Visual Studio
Llamado por Microsoft Excel justo después de que una función de hoja de cálculo XLL devuelve unXLOPER12XLOPER/ con un conjunto de marcas que le indica que hay memoria que el XLL todavía necesita liberar. Esto permite al XLL devolver matrices, cadenas y referencias externas asignadas dinámicamente a la hoja de cálculo sin pérdidas de memoria. Para obtener más información, consulte Administración de memoria en Excel.
A partir de Excel 2007, se admiten la función xlAutoFree12 y el tipo de datos XLOPER12 .
Excel no requiere un XLL para implementar y exportar ninguna de estas funciones. Sin embargo, debe hacerlo si las funciones XLL devuelven un XLOPER o XLOPER12 que se ha asignado dinámicamente o que contiene punteros a la memoria asignada dinámicamente. Asegúrese de que la elección de cómo administrar la memoria de estos tipos es coherente en todo el XLL y con la forma en que implementó xlAutoFree y xlAutoFree12.
Dentro de la función xlAutoFree/ xlAutoFree12 , las devoluciones de llamada en Excel están deshabilitadas, con una excepción: xlFree se puede llamar para liberar memoria asignada por Excel.
void WINAPI xlAutoFree(LPXLOPER pxFree);
void WINAPI xlAutoFree12(LPXLOPER12 pxFree);
Parameters
pxFree (LPXLOPER en el caso de xlAutoFree)
pxFree (LPXLOPER12 en el caso de xlAutoFree12)
Puntero al XLOPER o al XLOPER12 que tiene memoria que debe liberarse.
Valor de la propiedad/valor devuelto
Esta función no devuelve un valor y debe declararse como nula.
Comentarios
Cuando Excel está configurado para usar la actualización del libro multiproceso, se llama a xlAutoFree/ xlAutoFree12 en el mismo subproceso usado para llamar a la función que lo devolvió. La llamada a xlAutoFree/ xlAutoFree12 siempre se realiza antes de que las celdas de la hoja de cálculo siguientes se evalúen en dicho subproceso. Esto simplifica el diseño de subprocesos seguros en tu XLL.
Si la función xlAutoFree/ xlAutoFree12 que proporciona examina el campo xltype de pxFree, recuerde que el bit xlbitDLLFree seguirá estando establecido.
Ejemplo
Implementación de ejemplo 1
El primer código de \SAMPLES\EXAMPLE\EXAMPLE.C
muestra una implementación muy específica de xlAutoFree, que está diseñada para funcionar con una sola función, fArray. En general, el XLL tendrá más de una función que devuelve memoria que debe liberarse, en cuyo caso se requiere una implementación menos restringida.
Implementación de ejemplo 2
La segunda implementación de ejemplo es coherente con las suposiciones usadas en los ejemplos de creación de XLOPER12 de la sección 1.6.3, xl12_Str_example, xl12_Ref_example y xl12_Multi_example. Las suposiciones son que, cuando se ha establecido el bit xlbitDLLFree , toda la memoria de cadena, matriz y referencia externa se ha asignado dinámicamente mediante malloc, por lo que debe liberarse en una llamada a free.
Implementación de ejemplo 3
La tercera implementación de ejemplo es coherente con un XLL donde las funciones exportadas que devuelven XLOPER12s asignan cadenas, referencias externas y matrices mediante malloc, y donde el propio XLOPER12 también se asigna dinámicamente. Devolver un puntero a un XLOPER12 asignado dinámicamente es una manera de asegurarse de que la función es segura para subprocesos.
//////////////////////////////////////////
// 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);
}
Vea también
Administrador de complementos y funciones de la interfaz de XLL