2011-01-14 16 views
6

Estoy en Windows XP usando Visual Studio 6 (sí, sé que es viejo) construyendo/manteniendo una DLL de C++. Me encontré con un problema con fopen al no poder abrir un archivo existente, siempre devuelve NULL.¿Por qué no abrirá un archivo que existe?

He intentado:

  • Comprobación errno y _doserrno fijando tanto a cero y después de comprobar de nuevo, ambos siguen siendo cero, y por lo tanto GetLastError() indica que no hay errores. Sé que fopen no está obligado a establecer errno cuando encuentra un error de acuerdo con un estándar de C.
  • Hardcoding de la ruta del archivo, que no son relativos.
  • Probé en otra máquina de desarrollo que tiene el mismo resultado.

Lo realmente extraño es que CreateFile funciona y el archivo se puede leer con ReadFile. Creemos que esto funciona en una compilación de lanzamiento, sin embargo, también estamos viendo un comportamiento muy extraño en otras áreas de la aplicación y no estamos seguros si esto está relacionado.

El código está debajo, no veo nada raro, se ve bastante estándar para mí. El archivo fuente no ha cambiado por menos de medio año.

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 no es realmente C++. Ciertamente etiquetar C y C++ no tiene sentido. Decide un idioma, tanto en tus etiquetas como en tu código. –

+0

Ah, y en cuanto a la pregunta, compruebe que tiene permiso para acceder al archivo. No solo tiene que existir: su programa debe poder acceder a él. –

+0

@Tomalak: Sí, lo tenemos, VC++ 6.0 no cumple con los estándares. Pero es confuso decirle a la gente que no es C++ cuando claramente lo dice. Ciertamente no es C, ¿cuál es la alternativa? Estoy totalmente de acuerdo en que etiquetar tanto C como C++ no tiene sentido. –

Respuesta

2

Su función tiene un tipo de retorno HRESULT (donde 0 es bueno) pero devuelve un booleano (donde 0 es malo). Eso no puede ser correcto ...

+0

Mi error, debería haber sido S_FALSE. – void

1

Suponiendo que tiene una versión razonable de VC6, entonces tiene el código fuente del CRT, y puede pasar a la llamada fopen, y hasta la llamada CreateFile que el CRT hará. (¡Prepárate para que esté bastante lejos!)

+0

Encontré las fuentes de CRT del disco de instalación y puse en fopen. Afortunadamente, no tuve que bajar demasiado para descubrir la causa. (Ver pregunta original) – void

0

poner el punto de interrupción en la línea externa, activarlo en el depurador, ingresar "ERR, hr" en la ventana "Observar", ejecutar la línea y marcar Ver cuál era el problema . Lo más probable es que sean permisos de acceso.

9

La respuesta:

he encontrado la causa, demasiados identificadores de archivo abierto causa por algunos cambios recientes en la aplicación. Sin embargo, esto no cambió el código, por lo que este error ha estado presente por un tiempo. Entré en la función fopen hasta una función llamada _getstream. Esto intenta encontrar una secuencia que no esté en uso, la función busca una tabla de 512 secuencias. De hecho, todas las 512 en uso y otras llamadas a fopen están fallando. Utilicé la herramienta handle de sysinternals para ver el número de identificadores usados.

+0

por favor revisa mi respuesta – rashok

0

Ya tiene 512 archivos abiertos.

Solo podemos retener 512 archivos abiertos en la aplicación de VC. Estoy sugiriendo cerrar los archivos innecesarios usando fclose.

Cuestiones relacionadas