2010-10-21 17 views
24

La función fopen devuelve un puntero a una estructura FILE, que debe considerarse un valor opaco, sin tener en cuenta su contenido o significado.¿Cómo obtengo el archivo HANDLE de la estructura fopen FILE?

En Windows, el tiempo de ejecución de C es un contenedor de la API de Windows, y la función fopen se basa en la función CreateFile. La función CreateFile devuelve un HANDLE, que es utilizado por otra API de Windows.

Ahora, necesito usar la API de Windows en el interior de una biblioteca que usa fopen y FILE*. Entonces, ¿hay alguna manera de obtener el HANDLE de la estructura FILE? Como esto es específico del compilador, me refiero a la biblioteca de tiempo de ejecución de MSVC.

Entiendo que esto sería un hack feo, no portátil, y que podría romperse si Microsoft cambia el formato interno de FILE ... pero estoy desarrollando en un sistema cerrado (es decir, en un sistema integrado con Windows CE) y la refacturación de la biblioteca sería difícil y consumiría mucho tiempo.

+1

Muy buena pregunta, que se ocupó de éste hace a mí mismo más de 2 años. –

Respuesta

15

Use _fileno seguido de _get_osfhandle. No se olvide de _close cuando haya terminado.

EDITAR: no es claro para mí que _get_osfhandle es compatible con WinCE. Sin embargo, los documentos para WinCE _fileno dicen que devuelve un "identificador de archivo" en lugar de "descriptor". YMMV, pero esto sugiere que quizás solo pueda usar el valor de retorno _fileno directamente como manejador en WinCE.

EDITAR: # 2 Esa teoría es compatible con this person's experience.

"Si se echa un vistazo a los ficheros de cabecera que he publicado a la lista el Ene 29 de se puede ver cómo he manejado el problema de los archivos de creación/mango. Yo no tenía para reemplazar todos los archivos * elementos con . handles Ver el siguiente fragmento de fileio.cpp:

#ifndef q4_WCE 

    FlushFileBuffers((HANDLE) _get_osfhandle(_fileno(_file))); 
    HANDLE h = ::CreateFileMapping((HANDLE) 
_get_osfhandle(_fileno(_file)), 
         0, PAGE_READONLY, 0, len, 0); 
#else 

    FlushFileBuffers((HANDLE) _fileno(_file)); 
    HANDLE h = ::CreateFileMapping((HANDLE) _fileno(_file), 
        0, PAGE_READONLY, 0, len, 0); 
#endif //q4_WCE 

resulta que _fileno devuelve un identificador Sólo hay que echarlo "..

+1

Gracias, _fileno fue lo suficientemente bueno para mi problema con Windows CE, pero su respuesta parece realmente "portátil" en todas las plataformas MS con cualquier versión de MSVC. – Wizard79

4

En Linux, existe la función int fileno(FILE *); que devuelve el descriptor de archivo (el que fue devuelto por la función de bajo nivel open) del FILE*.

No sé si se aplica a Windows y devuelve el identificador aunque?

+1

Hmm, eso es posible: http://msdn.microsoft.com/en-us/library/ee479262.aspx indica que "_fileno obtiene el identificador de archivo asociado con la secuencia". Al menos en Windows CE debería funcionar. – Wizard79

+1

Es solo una función compatible para * nix. Las asas tienen un tamaño de puntero, 8 bytes en Win64. –

2

Para C, prueba este

HANDLE foo = (HANDLE)_get_osfhandle(fileno(fopen("bar.txt", "w"))); 
+0

Usado más tarde, esto me indica que el identificador no es válido, p. Ej. stdout. – imallett

Cuestiones relacionadas