Partager via


Gestion de la mémoire dans Excel (traduction automatique)

Dernière modification : vendredi 4 novembre 2011

S’applique à : Excel 2010 | Office 2010 | VBA | Visual Studio

Dans cet article
Mémoire XLOPER/XLOPER12
Libération de la mémoire XLOPER/XLOPER12 allouée par Excel
Renvoi XLOPER/XLOPER12s être libéré par Excel
Renvoi XLOPER/XLOPER12s être libéré par la DLL
Retourner des Arguments de la modifier en Place
Strings
Stockage permanent (noms binaires)
Pile de Excel

Important

Cet article a été traduit automatiquement, voir l’avertissement. Vous pouvez consulter la version en anglais de cet article ici.

La gestion de la mémoire est la question la plus importante si vous voulez créer des XLL efficaces et stables. Une gestion incorrecte de la mémoire peut induire toute une variété de problèmes dans Microsoft Excel, de problèmes mineurs comme l’initialisation ou l’allocation de mémoire insuffisante et les petites fuites de mémoire, jusqu’à des problèmes majeurs comme la déstabilisation d’Excel.

Mauvaise gestion de mémoire est la source la plus courante de sérieuses problèmes ajouter dans liés. Par conséquent, vous devez créer votre projet grâce à une stratégie cohérente et bien-étudié traversant sur la gestion de la mémoire.

Gestion de la mémoire est devenue plus complexe dans Microsoft Office Excel 2007 avec l'introduction de recalcul du classeur multithread. Si vous souhaitez créer et exporter des fonctions de feuille de calcul thread-safe, vous devez gérer les conflits en résultants qui peuvent se produire lorsque plusieurs threads sont en concurrence pour l'accès.

Il existe des considérations relatives à la mémoire pour les types de structure de trois données suivants :

  • XLOPERs et XLOPER12s

  • Chaînes qui ne sont pas dans un XLOPER ou XLOPER12

  • baies FP et FP12

Mémoire XLOPER/XLOPER12

La structure de données XLOPER/XLOPER12 a plusieurs sous-types qui contiennent des pointeurs vers les blocs de mémoire, à savoir les chaînes (xltypeStr), les baies (xltypeMulti) et les références externes (xltypeRef). Notez également que les baies xltypeMulti peuvent contenir des XLOPER/XLOPER12s de chaîne qui à son tour pointent vers les autres blocs de mémoire.

Vous pouvez créer un XLOPER/XLOPER12 de plusieurs manières :

  • Par Excel lors de la préparation des arguments à passer à une fonction XLL

  • Par Excel lors du renvoi d'un XLOPER ou XLOPER12 dans une API C appeler

  • Par votre DLL lors de la création des arguments à passer à une API C appeler

  • Par votre DLL lors de la création d'une valeur de retour de fonction XLL

Un bloc de mémoire dans un des types pointant vers la mémoire peut être alloué de plusieurs manières :

  • Il peut être un bloc statique dans votre DLL en dehors de tout code de fonction, auquel cas vous n'avez pas à allouer ou libérer la mémoire.

  • Il peut être un bloc statique dans votre DLL dans du code de fonction, auquel cas vous n'avez pas à allouer ou libérer la mémoire.

  • Il peut être dynamiquement alloué et libéré par votre DLL de plusieurs façons possibles : malloc et free, new et delete et ainsi de suite.

  • Il peut être dynamiquement alloué par Excel.

Étant donné le nombre d'origines possibles pour la mémoire de XLOPER/XLOPER12 et le nombre de situations dans lequel la XLOPER/XLOPER12 pourraient avoir eu cette mémoire affectée, il n'est pas surprenant que ce sujet peut sembler très difficile. Toutefois, la complexité peut être considérablement réduite si vous suivez les règles et consignes de plusieurs.

Règles pour l'utilisation avec XLOPER/XLOPER12

  • N'essayez pas de libérer de la mémoire ou écraser XLOPERs/XLOPER12s qui sont passés comme arguments à votre fonction XLL. Vous devez considérer ces arguments en lecture seule. Pour plus d'informations, consultez « Returning XLOPER ou XLOPER12 par les Arguments de modification en Place » dans Problèmes de développement XLL Excel connus (traduction automatique).

  • Si Excel a alloué la mémoire pour un XLOPER/XLOPER12 renvoyé à votre DLL dans un appel à l'API C :

    • Vous devez libérer la mémoire lorsque vous n'avez plus besoin du XLOPER/XLOPER12 à l'aide d'un appel à xlFree (traduction automatique). Ne pas utiliser toute autre méthode, telles que libre ou supprimer pour libérer la mémoire.

    • Si le type retourné est xltypeMulti, ne remplacent pas les XLOPER/XLOPER12s dans la baie, surtout si elles contiennent des chaînes, et surtout pas où vous voulez remplacer par une chaîne.

    • Si vous souhaitez renvoyer le XLOPER/XLOPER12 dans Excel en tant que valeur de retour de la fonction de votre DLL, vous devez indiquer à Excel qu'il y a mémoire Excel doit libérer lorsque vous avez terminé.

  • Vous devez uniquement appeler xlFree sur un XLOPER/XLOPER12 a été créé en tant que la valeur de retour pour un appel API C.

  • Si votre DLL a alloué la mémoire pour un XLOPER/XLOPER12 qui vous souhaitez revenir à Excel en tant que valeur de retour de la fonction de votre DLL, vous devez indiquer à Excel qu'il y a mémoire la DLL doit libérer.

Instructions pour la gestion de la mémoire

  • Soyez cohérent dans votre DLL dans la méthode que vous utilisez pour allouer et libérer de la mémoire. Éviter de mélanger des méthodes. Une bonne approche consiste à encapsuler la méthode que vous utilisez dans une classe de mémoire ou une structure, au sein de laquelle vous pouvez modifier la méthode utilisée sans modifier votre code dans de nombreux endroits.

  • Lorsque vous créez des tableaux de xltypeMulti dans votre DLL, soyez cohérent dans la manière d'allouer de mémoire pour les chaînes : toujours dynamiquement les allouer la mémoire ou de toujours utiliser la mémoire statique. Si vous faites cela, lorsque vous êtes libérer la mémoire, vous savez que vous devez toujours ou jamais libérer les chaînes.

  • Effectuer des copies de profondeur de mémoire allouée par Excel lorsque vous copiez un XLOPER/XLOPER12 créés par Excel.

  • Ne placez pas de chaîne allouée Excel XLOPER/XLOPER12s dans les tableaux de xltypeMulti. Effectuer des copies approfondies des chaînes et stocker des pointeurs vers les copies dans le tableau.

Libération de la mémoire XLOPER/XLOPER12 allouée par Excel

Pensez à la commande XLL suivante, qui utilise xlGetName pour obtenir une chaîne contenant le chemin d'accès et le nom de la DLL et l'affiche dans une boîte de dialogue d'alerte à l'aide de xlcAlert.

int WINAPI show_DLL_name(void)
{
    XLOPER12 xDllName;
    if(Excel12(xlfGetName, &xDllName, 0) == xlretSuccess)
    {
        // Display the name.
        Excel12(xlcAlert, 0, 1, &xDllName);
        // Free the memory that Excel allocated for the string.
        Excel12(xlFree, 0, 1, &xDllName);
    }
    return 1;
}

Lorsque la fonction n'a plus besoin la mémoire vers lequel pointe xDllName, il peut libérer à l'aide d'un appel à fonction xlFree (traduction automatique), l'une des fonctions DLL seule API C.

La fonction xlFree est entièrement documentée dans la section Références de fonction (voir Fonctions de l’API C appelables uniquement depuis une DLL ou XLL (traduction automatique)), mais n'oubliez pas de ce qui suit :

  • Vous pouvez passer des pointeurs à plusieurs XLOPER/XLOPER12s dans un seul appel à xlFree, ne limité que par le nombre d'arguments de fonction prise en charge dans la version en cours d'exécution d'Excel (30 dans Excel 2003, 255 commençant dans Excel 2007).

  • xlFree définit le pointeur confinée à NULL pour assurer la sécurité essayant de libérer un XLOPER/XLOPER12 qui a déjà été libérée. xlFree est la seule fonction d'API c qui modifie ses arguments.

  • Vous pouvez en toute sécurité appeler xlFree sur n'importe quel XLOPER/XLOPER12 utilisé pour la valeur de retour d'un appel à l'API C, indépendamment de si elle contient un pointeur vers la mémoire.

Renvoi XLOPER/XLOPER12s être libéré par Excel

Supposons que vous souhaitez modifier l'exemple de commande dans la section précédente et remplacez-la par une fonction de feuille de calcul qui renvoie le chemin et nom de la DLL lorsqu'il est passé un argument de Booleantrue et #N/A dans le cas contraire. Clairement, vous ne pouvez pas appeler xlFree pour libérer la mémoire de chaîne avant de retourner vers Excel. Toutefois, si elle n'est pas libérée à un moment donné, la macro complémentaire manquera de mémoire chaque fois que la fonction est appelée. Pour contourner ce problème, vous pouvez définir un bit dans le champ xltype de la XLOPER/XLOPER12, définie comme xlbitXLFree dans xlcall.h. Définition de ce paramètre indique à Excel qu'il doit libérer la mémoire renvoyée lorsqu'il a fini de copier la valeur.

Example

L'exemple de code suivant montre la commande XLL dans la section précédente, convertie en une fonction de feuille de calcul XLL.

LPXLOPER12 WINAPI get_DLL_name(int calculation_trigger)
{
    static XLOPER12 xRtnValue; // Not thread-safe

    Excel12(xlfGetName, &xRtnValue, 0);

// If xlfGetName failed, xRtnValue will be #VALUE!
    if(xRtnValue.xltype == xltypeStr)
    {
// Tell Excel to free the string memory after
// it has copied out the return value.
        xRtnValue.xltype |= xlbitXLFree;
    }
    return &xRtnValue;
}

Fonctions XLL qui utilisent XLOPER/XLOPER12s doivent être déclarées comme prise et le renvoi des pointeurs vers XLOPER/XLOPER12s. L'utilisation dans cet exemple d'un XLOPER12 au sein de la fonction statique n'est pas thread-safe. Vous ne pouvez pas correctement enregistrer cette fonction en tant que thread-safe, mais vous risquerait de xRtnValue est remplacé par un thread avant que si un autre thread s'était terminé avec lui.

Vous devez définir xlbitXLFree après l'appel pour le rappel d'Excel qui alloue. Si vous la définissez avant cela, il est écrasé et n'a pas l'effet souhaité. Si vous avez l'intention d'utiliser la valeur en tant qu'argument dans un appel à une autre fonction d'API c avant de retourner à la feuille de calcul, vous devez définir ce bit suite à l'appel de ce type. Dans le cas contraire, effet de dérouter les fonctions qui ne masquez pas ce bit avant de vérifier le type de XLOPER/XLLOPER12.

Renvoi XLOPER/XLOPER12s être libéré par la DLL

Un problème similaire à ceci se produit lorsque votre XLL a alloué la mémoire pour un XLOPER/XLOPER12 et souhaite retourner vers Excel. Excel reconnaît un autre bit qui peut être définie dans le champ xltype de XLOPER/XLOPER12, définie comme xlbitDLLFree dans xlcall.h.

Lorsqu'Excel reçoit an XLOPER/XLOPER12 avec ce bit est défini, il essaie d'appeler une fonction qui doit être exportée par la XLL appelée xlAutoFree (pour XLOPERs) ou xlAutoFree12 (pour XLOPER12s). Cette fonction est décrite plus en détail dans la référence de fonction (voir Gestionnaire de compléments et fonctions d’interface XLL (traduction automatique)), mais un exemple d'implémentation minimale est indiquée ici. Son but est de libérer la mémoire XLOPER/XLOPER12 d'une manière qui est conforme à la façon dont il a été alloué à l'origine.

Examples

L'exemple de fonction suivant effectue la même que la fonction précédente à ceci près qu'il consigne le texte « le chemin d'accès complet de cette DLL est » avant le nom de la DLL.

#include <string.h>
LPXLOPER12 WINAPI get_DLL_name_2(int calculation_trigger)
{
    static XLOPER12 xRtnValue; // Not thread-safe

    Excel12(xlfGetName, &xRtnValue, 0);

// If xlfGetName failed, xRtnValue will be #VALUE!
    if(xRtnValue.xltype != xltypeStr)
        return &xRtnValue;

// Make a copy of the DLL path and file name.
    wchar_t *leader = L"The full pathname for this DLL is ";
    size_t leader_len = wcslen(leader);
    size_t dllname_len = xRtnValue.val.str[0];
    size_t msg_len = leader_len + dllname_len;
    wchar_t *msg_text = (wchar_t *)malloc(msg_len + 1);
    wcsncpy_s(msg_text + 1, leader, leader_len);
    wcsncpy_s(msg_text + 1 + leader_len, xRtnValue.val.str + 1,
        dllname_len);
    msg_text[0] = msg_len;

// Now the original string has been copied Excel can free it.
    Excel12(xlFree, 0, 1, &xRtnValue);
// Now reuse the XLOPER12 for the new string.
    xRtnValue.val.str = msg_text;
// Tell Excel to call back into the DLL to free the string
// memory after it has copied out the return value.
    xRtnValue.xltype     = xltypeStr | xlbitDLLFree;
    return &xRtnValue;
}

Une implémentation minimale suffisante de xlAutoFree12 dans la XLL exportées de la fonction précédente se présente comme suit.

void WINAPI xlAutoFree12(LPXLOPER12 p_oper)
{
    if(p_oper->xltype == (xltypeStr | xlbitDLLFree))
        free(p_oper->val.str);
}

Cette implémentation n'est suffisante si la XLL retourne uniquement les chaînes de XLOPER12, et ces chaînes ne sont alloués à l'aide de malloc. Notez que le test

if(p_oper->xltype == xltypeStr)

échouerait dans ce cas, car xlbitDLLFree est défini.

En règle générale, les xlAutoFree et xlAutoFree12 doivent être implémentées afin qu'ils libérer la mémoire allouée avec baies xltypeMulti de création de XLL et xltypeRef des références externes.

Vous pouvez décider d'implémenter vos fonctions XLL afin qu'ils tout retour dynamiquement alloués XLOPERs et XLOPER12s. Dans ce cas, vous devrez définir xlbitDLLFree sur tous les XLOPERs et XLOPER12s sans tenir compte du sous-type. Vous devez également implémenter xlAutoFree et xlAutoFree12 afin que cette mémoire a été libérée et également les modules de mémoire indiqué dans la XLOPER/XLOPER12. Cette approche consiste à sécuriser le thread de la valeur de retour. Par exemple, la fonction précédente peut être réécrit comme suit.

#include <string.h>
LPXLOPER12 WINAPI get_DLL_name_3(int calculation_trigger)
{
// Thread-safe
    LPXLOPER12 pxRtnValue = (LPXLOPER12)malloc(sizeof(XLOPER12));

    Excel12(xlfGetName, pxRtnValue, 0);

// If xlfGetName failed, pxRtnValue will be #VALUE!
    if(pxRtnValue->xltype != xltypeStr)
    {
// Even though an error type does not point to memory,
// Excel needs to pass this oper to xlAutoFree12 to
// free pxRtnValue itself.
        pxRtnValue->xltype |= xlbitDLLFree;
        return pxRtnValue;
    }

// Make a copy of the DLL path and file name.
    wchar_t *leader = L"The full pathname for this DLL is ";
    size_t leader_len = wcslen(leader);
    size_t dllname_len = pxRtnValue->val.str[0];
    size_t msg_len = leader_len + dllname_len;
    wchar_t *msg_text = (wchar_t *)malloc(msg_len + 1);
    wcsncpy_s(msg_text + 1, leader, leader_len);
    wcsncpy_s(msg_text + 1 + leader_len, pxRtnValue->val.str + 1,
        dllname_len);
    msg_text[0] = msg_len;

// Now the original string has been copied Excel can free it.
    Excel12(xlFree, 0, 1, pxRtnValue);
// Now reuse the XLOPER12 for the new string.
    pxRtnValue->val.str = msg_text;
    pxRtnValue->xltype = xltypeStr | xlbitDLLFree;
    return pxRtnValue;
}

void WINAPI xlAutoFree12(LPXLOPER12 p_oper)
{
    if(p_oper->xltype == (xltypeStr | xlbitDLLFree))
        free(p_oper->val.str);

    free(p_oper);
}

Pour plus d'informations sur xlAutoFree et xlAutoFree12, consultez xlAutoFree/xlAutoFree12 (traduction automatique).

Retourner des Arguments de la modifier en Place

Excel permet à une fonction XLL retourner une valeur en modifiant un argument en place. Vous ne pouvez le faire avec un argument passé comme un pointeur. Pour travailler comme suit, la fonction doit être enregistrée dans un moyen qui indique à Excel quel argument sera modifiée.

Cette méthode de retourner une valeur est prise en charge pour tous les types de données qui peuvent être passées par pointeur, mais elle est particulièrement utile pour les types suivants :

  • Chaînes d'octets ASCII-longueur comptée et se terminant par null

  • -Longueur comptée et se terminant par null chaînes de caractères Unicode (qui commence dans Excel 2007)

  • tableaux en virgule flottante FP

  • FP12 les baies à virgule flottante (qui commence dans Excel 2007)

Notes

Vous ne devez pas essayer de renvoyer XLOPERs ou XLOPER12s de cette manière. Pour plus d'informations, consultez Problèmes de développement XLL Excel connus (traduction automatique).

L'avantage d'utiliser cette technique, au lieu de simplement à l'aide de l'instruction return, est que Excel alloue la mémoire pour les valeurs de retour. Une fois qu'Excel a terminé de lire les données renvoyées, il libère la mémoire. Cela place la mémoire des tâches de gestion à partir de la fonction XLL. Cette technique est thread-safe : si appelée en même temps par Excel sur différents threads, chaque appel de fonction sur chaque thread possède sa propre mémoire tampon.

Il est notamment utile pour les types de données précédemment répertoriées dans la mesure où le mécanisme d'appel dans la DLL à post-return de mémoire libre existe pour XLOPER/XLOPER12s n'existe pas de chaînes simples et des tableaux de FP/FP12. Par conséquent, lorsqu'elle retourne une chaîne créée par le DLL ou un tableau à virgule flottante, vous disposez des choix suivants :

  • Définissez un pointeur persistent dans une mémoire tampon allouée de manière dynamique, retourne le pointeur. Lors du prochain appel à la fonction (1) Vérifiez que le pointeur n'est pas null, (2) libre les ressources allouées lors du précédent appel et réinitialisez le pointeur à null, réutilisation (3) le pointeur pour un bloc de mémoire qui vient d'être alloué.

  • Créer des chaînes et des tableaux dans un tampon statique ne devant pas être libéré et renvoyer un pointeur vers qui.

  • Modifier un argument en place, écrivez votre chaîne ou un tableau directement dans l'espace réservé par Excel.

Dans le cas contraire, vous devez créer un XLOPER/XLOPER12 et permet de libérer les ressources xlbitDLLFree et xlAutoFree/xlAutoFree12.

La dernière option peut être la plus simple dans les cas dans lesquels un argument du même type que la valeur de retour sont en cours transmis. Le point clé à retenir est que les tailles de tampon sont limitées et vous devez faire très attention ne pas à leur saturation. L'obtention de cette mauvaise peut tomber en panne Excel. Les tailles de tampon de chaînes et des tableaux de FP/FP12 sont traités ci-après.

Strings

Problèmes liés à la gestion de la mémoire de la chaîne sont sans doute la cause la plus fréquente d'instabilité dans des applications et des compléments. Il est compréhensible sans doute, étant donné la diversité des méthodes dans lequel les chaînes sont gérés : se terminant par null ou à longueur comptée (ou les deux) ; mémoires tampons statiques ou dynamiques ; longueur fixe ou presque illimitée ; gérée par le système d'exploitation (par exemple, OLE Bstr) de mémoire ou de chaînes non managées ; et ainsi de suite.

Les programmeurs C/C++ sont plus familiers avec les chaînes se terminant par null. La bibliothèque c standard est conçue pour fonctionner avec ces chaînes. Littéraux de chaîne statique dans le code sont compilés dans les chaînes se terminant par null. Sinon, Excel fonctionne avec des chaînes à longueur comptée qui ne sont pas en général null-terminées. La combinaison de ces faits nécessite une approche claire et cohérente au sein de votre DLL/XLL concernant le mode de gestion de chaînes et la mémoire de la chaîne.

Problèmes les plus courants sont les suivantes :

  • Le passage d'un pointeur null ou non valide pour une fonction qui attend un pointeur valide et ne le fait pas ou ne peut pas vérifier de validité du pointeur lui-même.

  • Le dépassement des limites d'une mémoire tampon de chaîne par une fonction qui ne le fait pas ou ne peut pas vérifier la longueur de la mémoire tampon par rapport à la longueur de la chaîne en cours d'écriture.

  • Essayez de libérer la mémoire tampon de chaîne qui est soit statique, ou a été libérée déjà ou n'a pas été allouée de manière cohérente avec la façon dont elle est libérée.

  • Ce résultat à partir de chaînes est allouée et puis ne pas libéré, généralement dans une fonction appelée fréquemment de fuites de mémoire.

Règles relatives aux chaînes

Comme avec XLOPER/XLOPERs, il existe des règles et consignes vous devez suivre. Les lignes directrices sont les mêmes telle qu'elle apparaît dans la section précédente. Les règles ici sont une extension des règles pour les chaînes.

règles

  • N'essayez pas de libérer de la mémoire ou de remplacer la chaîne XLOPER/XLOPER12s ou simple-longueur comptée ou se terminant par null chaînes passées comme arguments à votre fonction XLL. Vous devez considérer ces arguments en lecture seule.

  • Dans le cas où Excel alloue la mémoire pour une chaîne XLOPER/XLOPER12 pour la valeur de retour d'une fonction de rappel API C, utilisez xlFree pour la libérer, ou xlbitXLFree si renvoyer vers Excel à partir d'une fonction XLL.

  • Dans le cas où votre DLL alloue un tampon de chaîne pour un XLOPER/XLOPER12, libérer de manière cohérente avec comment vous allouée lorsque vous avez terminé, ou la xlbitDLLFree de jeu si renvoyer vers Excel à partir d'une fonction XLL et puis de le libérer dans xlAutoFree/xlAutoFree12.

  • Si Excel a alloué la mémoire pour un tableau xltypeMulti retourné à votre DLL dans un appel à l'API C, ne pas remplacer toute chaîne XLOPER/XLOPER12s dans le tableau. Ces tableaux doit uniquement être libérée à l'aide de xlFree, ou, si sont renvoyées par une fonction XLL, en définissant xlbitXLFree.

Prise en charge des Types de chaînes

API c xltypeStr XLOPER/XLOPER12s

Chaînes d'octets : XLOPER

Chaînes à caractères étendus : XLOPER12

Toutes les versions d'Excel

Démarrage en Excel 2007

Longueur maximale : 255 octets ASCII étendus

Longueur maximale 32 767 caractères Unicode

Premier octet (non signé) = longueur

Premier caractère Unicode = longueur

Important

Ne supposez pas le caractère null de fin de chaînes XLOPER ou XLOPER12.

Chaînes C/C++

Chaînes d'octets

Chaînes de caractères

Se terminant par null (char *) « C » Max length : 255 octets ASCII étendus

Se terminant par null (wchar_t *) longueur Maximum de « % C » 32 767 caractères Unicode

-Longueur comptée (unsigned char *) « D »

-Longueur comptée (wchar_t *) « % D »

Chaînes dans xltypeMulti XLOPER/XLOPER12 baies

Dans plusieurs cas, Excel crée un tableau de xltypeMulti à utiliser dans votre DLL/XLL. Plusieurs des fonctions d'informations XLM renvoient ces tableaux. Par exemple, la xlfGetWorkspace de fonction API C, lorsqu'il est passé de l' argument 44, retourne un tableau contenant les chaînes qui décrivent toutes les procédures DLL actuellement enregistrés. Le xlfDialogBox de fonction API C renvoie une copie modifiée de son argument de tableau contenant les copies approfondies des chaînes. Le moyen le plus courant qu'un XLL rencontre un tableau xltypeMulti est sans doute où il a été passé en tant qu'argument à une fonction XLL, ou il a été converti en ce type à partir d'une référence de plage. Dans ces derniers cas, Excel crée des copies approfondies des chaînes dans les cellules de la source et les points à celles-ci au sein de la baie.

Où vous souhaitez modifier ces chaînes dans votre DLL, vous devez effectuer vos propres copies profonds. Lorsque vous créez vos propres tableaux de xltypeMulti, vous ne devez pas placer chaîne allouée Excel XLOPER/XLOPER12s qu'ils contiennent. Cela risque de vous libèrent ne pas les correctement une version ultérieure, ou ne pas les libérer de tout. Là encore, vous devez effectuer des copies approfondies des chaînes et stocker des pointeurs vers les copies dans le tableau.

Exemples

L'exemple de fonction suivante crée une copie allouée de manière dynamique d'une chaîne Unicode de longueur comptée. Notez que l'appelant doit libérer en fin de compte de la mémoire allouée dans cet exemple à l'aide de [] delete, et que la chaîne source n'est pas supposée être null s'est arrêté. La chaîne de copie est tronquée si nécessaire pour la sécurité et n'est pas null s'est arrêté.

#include <string.h>
#define MAX_V12_STRBUFFLEN    32678
    
wchar_t * deep_copy_wcs(const wchar_t *p_source)
{
    if(!p_source)
        return NULL;

    size_t source_len = p_source[0];
    bool truncated = false;

    if(source_len >= MAX_V12_STRBUFFLEN)
    {
        source_len = MAX_V12_STRBUFFLEN - 1; // Truncate the copy
        truncated = true;
    }
    wchar_t *p_copy = new wchar_t[source_len + 1];
    wcsncpy_s(p_copy, p_source, source_len + 1);
    if(truncated)
        p_copy[0] = source_len;
    return p_copy;
}

Cette fonction peut être ensuite en toute sécurité utilisée pour copier un XLOPER12, comme illustré à la fonction XLL exportable suivante qui retourne une copie de son argument, s'il s'agit d'une chaîne. Tous les autres types sont retournées comme une chaîne de longueur nulle. Notez que les plages ne sont pas gérées, la fonction renvoie #VALUE!. La fonction doit être enregistrée comme prenant un argument de type u afin que les références sont transmis en tant que de valeurs. Cela équivaut à la T() de fonction de feuille de calcul intégrées à ceci près que AsText convertit également les erreurs pour les chaînes de longueur nulle. Cet exemple de code suppose que xlAutoFree12 libère le pointeur passée, ainsi que son contenu, à l'aide de delete.

LPXLOPER12 WINAPI AsText(LPXLOPER12 pArg)
{
    LPXLOPER12 pRtnVal = new XLOPER12;
// If the input was an array, only operate on the top-left element.
    LPXLOPER *pTemp;
    if(pArg->xltype == xltypeMulti)
        pTemp = pArg->val.array.lparray;
    else
        pTemp = pArg;

    switch(pTemp->xltype)
    {
        case xltypeErr:
        case xltypeNum:
        case xltypeMissing:
        case xltypeNil:
        case xltypeBool:
            pRtnVal->xltype = xltypeStr | xlbitDLLFree;
            pRtnVal->val.str = deep_copy_wcs(L"\000");
            return pRtnVal;

        case xltypeStr:
            pRtnVal->xltype = xltypeStr | xlbitDLLFree;
            pRtnVal->val.str = deep_copy_wcs(pTemp->val.str);
            return pRtnVal;
        
        default: // xltypeSRef, xltypeRef, xltypeFlow, xltypeInt
            pRtnVal->xltype = xltypeErr | xlbitDLLFree;
            pRtnVal->val.err = xlerrValue;
            return pRtnVal;
    }
}

Retourner des Arguments de chaîne de modifier en Place

Arguments inscrit en tant que types F, G, F% et G% peuvent être modifiés en place. Lorsque Excel se prépare les arguments de chaîne pour ces types, il crée une mémoire tampon de longueur maximale. Puis il copie la chaîne d'arguments dans qui, même si cette chaîne est beaucoup plus courte. Ainsi, la fonction XLL écrire sa valeur de retour directement dans la même mémoire.

Les tailles de tampon compartimentés pour ces types sont les suivantes :

  • Chaînes d'octets : 256 octets ainsi que le compteur Longueur (type G) ou la terminaison null (type F).

  • Les chaînes Unicode : 32 768 caractères étendus (65 536 octets) y compris le compteur Longueur (type G %) ou la terminaison null (type F %).

Notes

Vous ne pouvez pas appeler une telle fonction directement à partir de Visual Basic pour Applications (VBA) dans la mesure où rien ne garantit qu'une mémoire tampon suffisant a été alloué. Vous pouvez uniquement appeler ce type de fonction à partir d'une autre DLL en toute sécurité si vous avez passé explicitement un tampon assez grand.

Voici un exemple d'une fonction XLL qui inverse d'une chaîne passée se terminant par null caractère élargi à l'aide de la wcsrev de fonction de bibliothèque standard. L'argument serait dans ce cas être inscrit en tant que type F%.

void WINAPI reverse_text_xl12(wchar_t *text)
{
    _wcsrev(text);
}

Stockage permanent (noms binaires)

Noms binaires sont définis et associés à des blocs de binaire, autrement dit, les données non structurées, qui sont stockées avec le classeur. Ils sont créés à l'aide de la fonction xlDefineBinaryName, et les données sont récupérées à l'aide de la fonction xlGetBinaryName. Les deux fonctions sont décrites en détail dans la référence de fonction (voir Fonctions de l’API C appelables uniquement depuis une DLL ou XLL (traduction automatique)), et utilisent tous deux le xltypeBigDataXLOPER/XLOPER12.

Pour plus d'informations sur les problèmes connus qui limitent les applications pratiques des noms binaires, consultez Problèmes de développement XLL Excel connus (traduction automatique).

Pile de Excel

Excel partage son espace de pile avec toutes les DLL chargées. Espace de pile est généralement plus qu'adéquat pour une utilisation ordinaire, et il est inutile de se soucier des il tant que vous suivez les instructions suivantes :

  • Ne transmettez pas très grandes structures comme arguments aux fonctions par valeur dans la pile. Passer des pointeurs ou références à la place.

  • Ne retournez pas de grandes structures sur la pile. Retournent des pointeurs vers la mémoire allouée de manière dynamique ou statique, ou utiliser les arguments passés par référence.

  • Ne déclarez pas de très grandes structures variables automatiques dans le code de fonction. Si vous en avez besoin, les déclarer comme static.

  • N'appelez pas les fonctions de manière récursive sauf si vous êtes sûr (e) de que la profondeur de la récursivité sera toujours superficielle. Essayez d'utiliser une boucle.

Lorsqu'une DLL rappelle dans Excel à l'aide de l'API C, Excel vérifie d'abord s'il y a suffisamment d'espace sur la pile pour l'appel de l'utilisation le plus défavorable qui a pu être établie. Si elle pense qu'il y a peut-être un espace insuffisant, il va échouer l'appel à être sécurisés, même s'il peut effectivement ont été suffisamment d'espace pour cet appel particulier. Dans ce cas, les rappels renvoient le xlretFailed de code. Pour une utilisation ordinaire de l'API c et de la pile, il s'agit d'une cause probable de l'échec d'un appel API C.

Si vous êtes concerné, ou simplement curieux, ou vous souhaitez éliminer le manque d'espace de pile un motif de l'erreur inexpliquée du système, vous pouvez connaître l'espace pile disponible avec un appel à la fonction xlStack (traduction automatique).

Notes

Avertissement traduction automatique : cet article a été traduit par un ordinateur, sans intervention humaine. Microsoft propose cette traduction automatique pour offrir aux personnes ne maîtrisant pas l’anglais l’accès au contenu relatif aux produits, services et technologies Microsoft. Comme cet article a été traduit automatiquement, il risque de contenir des erreurs de grammaire, de syntaxe ou de terminologie.

Voir aussi

Concepts

Recalcul multithread dans Excel (traduction automatique)

Traitement multithread et contention de mémoire dans Excel (traduction automatique)

Développement de XLL Excel 2010 (traduction automatique)