xlAutoFree/xlAutoFree12
S’applique à: Excel 2013 | Office 2013 | Visual Studio
Appelé par Microsoft Excel juste après qu’une fonction de feuille de calcul XLL retourne uneXLOPER12XLOPER/ à celle-ci avec un ensemble d’indicateurs qui lui indique qu’il y a de la mémoire que le XLL doit toujours libérer. Le XLL peut ainsi renvoyer des matrices, des chaînes et des références externes allouées dynamiquement vers la feuille de calcul sans pertes de mémoire. Pour plus d’informations, reportez-vous à la rubrique Gestion de la mémoire dans Excel.
À compter d’Excel 2007, la fonction xlAutoFree12 et le type de données XLOPER12 sont pris en charge.
Excel n’a pas besoin d’un XLL pour implémenter et exporter l’une ou l’autre de ces fonctions. Toutefois, vous devez le faire si vos fonctions XLL retournent un XLOPER ou un XLOPER12 qui a été alloué dynamiquement ou qui contient des pointeurs vers la mémoire allouée dynamiquement. Assurez-vous que votre choix de gestion de la mémoire pour ces types est cohérent dans votre XLL et avec la façon dont vous avez implémenté xlAutoFree et xlAutoFree12.
Dans la fonction xlAutoFree/ xlAutoFree12 , les rappels dans Excel sont désactivés, à une exception près : xlFree peut être appelé pour libérer de la mémoire allouée à Excel.
void WINAPI xlAutoFree(LPXLOPER pxFree);
void WINAPI xlAutoFree12(LPXLOPER12 pxFree);
Paramètres
pxFree (LPXLOPER dans le cas de xlAutoFree)
pxFree (LPXLOPER12 dans le cas de xlAutoFree12)
Pointeur vers xlOPER ou le XLOPER12 dont la mémoire doit être libérée.
Valeur de propriété/valeur de renvoi
Cette fonction ne retourne pas de valeur et doit être déclarée comme retournant void.
Remarques
Quand Excel est configuré pour utiliser le recalcul de classeur multithread, xlAutoFree/ xlAutoFree12 est appelé sur le thread utilisé pour appeler la fonction qui l’a renvoyé. L’appel à xlAutoFree/ xlAutoFree12 est toujours effectué avant que d’autres cellules de la feuille de calcul soient évaluées sur ce thread. Cela simplifie la conception thread-safe dans votre XLL.
Si la fonction xlAutoFree/ xlAutoFree12 que vous fournissez examine le champ xltype de pxFree, n’oubliez pas que le bit xlbitDLLFree est toujours défini.
Exemple
Exemple d’implémentation 1
Le premier code de \SAMPLES\EXAMPLE\EXAMPLE.C
illustre une implémentation très spécifique de xlAutoFree, qui est conçue pour fonctionner avec une seule fonction, fArray. En règle générale, votre XLL aura plus d’une seule fonction retournant de la mémoire qui doit être libérée, auquel cas une implémentation moins restreinte est nécessaire.
Exemple d’implémentation 2
Le deuxième exemple d’implémentation est cohérent avec les hypothèses utilisées dans les exemples de création de XLOPER12 dans la section 1.6.3, xl12_Str_example, xl12_Ref_example et xl12_Multi_example. Les hypothèses sont que, lorsque le bit xlbitDLLFree a été défini, toute la mémoire de chaîne, de tableau et de référence externe a été allouée dynamiquement à l’aide de malloc, et doit donc être libérée dans un appel à free.
Exemple d’implémentation 3
Le troisième exemple d’implémentation est cohérent avec un XLL où les fonctions exportées qui retournent XLOPER12allouent des chaînes, des références externes et des tableaux à l’aide de malloc, et où le XLOPER12 lui-même est également alloué dynamiquement. Le retour d’un pointeur vers un XLOPER12 alloué dynamiquement est un moyen de s’assurer que la fonction est thread-safe.
//////////////////////////////////////////
// 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);
}
Voir aussi
Fonctions du Gestionnaire de compléments et de l’interface XLL