Question

Je suis sous Windows XP à l'aide de Visual Studio 6 (oui je sais qu'il est vieux) construire / maintenir une DLL C ++. Je rencontrais un problème avec fopen ne pas ouvrir un fichier existant, il retourne toujours NULL.

J'ai essayé:

  • Vérification errno et _doserrno en réglant les deux à zéro, puis les vérifier à nouveau, les deux restent zéro, et rapporte donc GetLastError () aucune erreur. Je sais fopen est pas tenu de errno lorsqu'il rencontre une erreur selon une norme C.
  • hardcoding le chemin du fichier, qui ne sont pas relatif.
  • Essayé sur une autre machine de développeurs qui le même résultat.

La chose vraiment étrange est des œuvres CreateFile et le fichier peut être lu avec ReadFile. Nous croyons que cela fonctionne dans une version release, mais nous voyons aussi un comportement très étrange dans d'autres domaines de l'application et nous ne sommes pas sûrs si cela est lié.

Le code est ci-dessous, je ne vois pas quelque chose de bizarre, il semble tout à fait standard pour moi. Le fichier source n'a pas changé depuis un peu moins d'une demi-année.

HRESULT CDataHandler::LoadFile( CStdString szFilePath )
{
    //Code
    FILE* pFile;
    if ( NULL == ( pFile = fopen( szFilePath.c_str(), "rb") ) )
    {
        return S_FALSE;
    }
    //More code
}

Pas de solution correcte

Autres conseils

Réponse:

Je trouve la cause, trop de descripteurs de fichiers ouverts provoquent par des récentes mises à jour de l'application. Ceux-ci, où le code ne change que si ce bug a été présent pendant un certain temps. Je suis entré dans le bas de la fonction fopen à une fonction appelée _getstream. Cette tentative de trouver un cours d'eau ne sont pas utilisés, les recherches de la fonction d'une table de 512 cours d'eau assez que tous les 512 où l'utilisation et d'autres appels à fopen où à défaut. J'ai utilisé l'outil de poignée de Sysinternals pour voir le nombre de poignées utilisées.

Votre fonction a un type de retour HRESULT (où 0 est bon), mais vous renvoie un booléen (où 0 est mauvais). Cela ne peut pas avoir raison ...

En supposant que vous avez une version raisonnable VC6, vous avez le code source au CRT, et vous pouvez entrer dans l'appel fopen, et tout le long de l'appel CreateFile que le CRT fera. (Préparez-vous à un long chemin vers le bas!)

scroll top