2011-01-14 17 views
6

Sono su Windows XP utilizzando Visual Studio 6 (sì, so che è vecchio) che costruisce/gestisce una DLL C++. Ho riscontrato un problema con fopen in mancanza di aprire un file esistente, restituisce sempre NULL.Perché fopen non riesce ad aprire un file esistente?

ho provato:

  • Controllo errno e _doserrno impostando sia a zero e poi il controllo di nuovo, entrambi rimangono a zero, e quindi GetLastError() segnala nessun errore. So che fopen non è obbligato a impostare errno quando incontra un errore secondo uno standard C.
  • Hardcoding del percorso del file, che non sono relativi.
  • Provato su un'altra macchina per sviluppatori che ha lo stesso risultato.

La cosa davvero strana è che CreateFile funziona e il file può essere letto con ReadFile. Crediamo che questo funzioni in una versione di rilascio, tuttavia stiamo anche osservando un comportamento molto strano in altre aree dell'applicazione e non siamo sicuri se questo è correlato.

Il codice è sotto, non vedo nulla di strano mi sembra abbastanza standard. Il file sorgente non è cambiato da poco meno di mezzo anno.

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

Visual C++ 6 non è realmente C++. Certamente codificare sia C che C++ è privo di senso. Scegli una lingua, sia nei tag che nel codice. –

+0

Oh, e come per la domanda, controlla di avere il permesso di accedere al file. Non deve solo esistere: il tuo programma deve essere in grado di accedervi. –

+0

@Tomalak: Sì, abbiamo capito, VC++ 6.0 non è conforme agli standard. Ma è confuso dire alla gente che non è C++ quando afferma chiaramente di essere. Non è certamente C, quindi qual è l'alternativa? Sono completamente d'accordo sul fatto che codificare C e C++ sia privo di senso. –

risposta

2

La funzione ha un tipo di ritorno HRESULT (dove 0 è buono) ma si restituisce un valore booleano (dove 0 è negativo). Non può essere giusto ...

+0

Il mio errore, avrebbe dovuto essere S_FALSE. – void

1

Supponendo che tu abbia una versione ragionevole di VC6, hai il codice sorgente per il CRT, e puoi passare alla chiamata fopen e fino alla chiamata CreateFile che il CRT farà. (Preparati a scendere parecchio!)

+0

Ho trovato i sorgenti CRT del disco di installazione e sono entrato in fopen. Fortunatamente non sono dovuto andare troppo oltre per scoprire la causa. (Vedere domanda originale) – void

0

inserisci punto di interruzione su linea fopen, attivalo in debugger, inserisci "ERR, hr" nella finestra "Guarda", esegui la linea e controlla Controlla quale era il problema . Molto probabilmente sono permessi di accesso.

9

La Risposta:

ho trovato la causa, troppi file aperti gestisce causa da alcuni recenti aggiornamenti per l'applicazione. Questi però non cambiano il codice, quindi questo bug è stato presente per un po '. Sono entrato nella funzione fopen fino a una funzione chiamata _getstream. Questo tenta di trovare un flusso non in uso, la funzione cerca una tabella di 512 flussi. Certo, basta tutti i 512 dove in uso e altre chiamate a fopen dove non ce l'hanno. Ho usato lo strumento handle da sysinternals per vedere il numero di maniglie utilizzate.

+0

si prega di controllare la mia risposta – rashok

0

Hai già 512 file aperti.

Possiamo contenere solo max 512 file aperti nell'applicazione VC. Sto suggerendo di chiudere i file non necessari utilizzando fclose.

Problemi correlati