2010-01-28 7 views
1

Dans mon application, j'ai besoin d'un accès direct à la variable _environ car je dois avoir quelque chose comme la glibc unsetenv (vous ne pouvez pas l'avoir avec setenv ou putenv).comment puis-je corriger l'erreur MSVC 2005: symbole externe non résolu __environ

Voici le code que je dois utiliser:

////////////////////// 
// unsetenv for WIN32, taken from libc source 
int unsetenv(const char *name) 
{ 
    size_t len; 
    char **ep; 

    if (name == NULL || *name == '\0' || strchr (name, '=') != NULL) 
    { 
     return -1; 
    } 

    len = strlen (name); 

    ep = _environ; 
    while (*ep != NULL) 
    if (!strncmp (*ep, name, len) && (*ep)[len] == '=') 
     { 
    /* Found it. Remove this pointer by moving later ones back. */ 
    char **dp = ep; 

    do 
     dp[0] = dp[1]; 
    while (*dp++); 
    /* Continue the loop in case NAME appears again. */ 
     } 
    else 
     ++ep; 

    return 0; 
} 

Il a bien fonctionné jusqu'à ce que nous avons eu quelques problèmes avec les manifestes sur certains systèmes, donc nous avons essayé d'utiliser la version statique de la bibliothèque d'exécution (/ MT drapeau).

Maintenant, je reçois cette erreur:

unresolved external symbol __environ 

je lis here et à beaucoup d'autres endroits que cette variable est devenue obsolète et dépréciés. Je m'interroge sur la solution possible. Je ne peux pas non plus utiliser la variable _wenviron car nous voulons prendre en charge Windows 98.

Dans les paramètres du projet, je l'ai explicitement configuré pour utiliser MBCS (c'est-à-dire, pas Unicode). Je suis un peu trébuché ici. Y a-t-il autre chose que je dois définir? Juste pour tester, j'ai aussi essayé la version Unicode. C'est à dire. ce code:

int unsetenv(const wchar_t *name) 
{ 
    size_t len; 
    wchar_t **ep; 

    if (name == NULL || *name == '\0' || wcschr (name, '=') != NULL) 
    { 
     return -1; 
    } 

    len = wcslen (name); 

    ep = _wenviron; 
    while (*ep != NULL) 
    if (!wcsncmp (*ep, name, len) && (*ep)[len] == '=') 
     { 
    /* Found it. Remove this pointer by moving later ones back. */ 
    wchar_t **dp = ep; 

    do 
     dp[0] = dp[1]; 
    while (*dp++); 
    /* Continue the loop in case NAME appears again. */ 
     } 
    else 
     ++ep; 

    return 0; 
} 

Je me demande un peu pourquoi même compilé parce que je l'ai explicitement mis à utiliser MBCS et non Unicode. Mais peut-être que cela veut dire autre chose. (Quelqu'un peut-il me éclairer ici?)

Quoi qu'il en soit, cela se traduit par ces erreurs:

1>AuxLib.obj : error LNK2001: unresolved external symbol __wenviron 
1>ExtractInfo.obj : error LNK2001: unresolved external symbol __environ 

AuxLib.obj est le fichier avec ce unsetenv(). Donc une erreur de plus qu'avant.

+0

Je lis entre les lignes ici, mais il semble que vous avez fait quelques expériences et vous Suis capable de lier à la variable _wenviron en utilisant les mêmes drapeaux de compilation et de liaison, mais pas _environ? –

+0

Je viens d'essayer ça: je l'ai recodé pour utiliser _wenviron (qui n'était pas vraiment une solution pour moi, mais juste pour tester), mais j'ai eu l'erreur: le symbole externe non résolu __wenviron – Albert

Répondre

0

Je ne suis pas sûr de comprendre, quel est le problème avec getenv_s()? C'est la fonction équivalente de la variable globale __environ. Il est multi-octets, pas unicode, donc il devrait fonctionner correctement sur toutes les plates-formes ciblées par le compilateur VS 2005. les « _S » signifie « sûr », ce qui signifie l'opération a été redessinée pour réduire exploitabilité par des pirates via des débordements de tampons, etc.

+0

Je dois ce code ci-dessus pour fonctionner. Ce code remplacera la mémoire où _environ pointe vers. Il n'y a pas de fonction MSVC que je connaisse qui puisse le faire. – Albert

+0

L'OP tente de supprimer une variable d'environnement de la variable libc globalement partagée. Je ne sais pas d'une fonction de bibliothèque qui effectue cette opération pour l'OP, et ce serait bien car elle pourrait le faire d'une manière thread-safe. –

+0

Désolé, je vois ça maintenant. De ce que j'ai vu, le seul moyen fiable de supprimer une variable d'environnement est d'utiliser la fonction Win32 SetEnvironmentVariable et de passer une valeur NULL pour la valeur. Cette API est uniquement prise en charge sur Windows 2000 et les versions ultérieures. –

Questions connexes