¿Cómo obtengo el archivo HANDLE de la estructura fopen FILE?

3 minutos de lectura

avatar de usuario
lornova

los fopen función devuelve un puntero a un FILE estructura, que debe ser considerada como un valor opaco, sin ocuparse de su contenido o significado.

En Windows, el tiempo de ejecución de C es un contenedor de la API de Windows y el fopen función se basa en la CreateFile función. los CreateFile función devuelve un HANDLEque 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 desde el FILE ¿estructura? 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 truco feo y no portátil, y que podría fallar si Microsoft cambia el formato interno de FILE… pero estoy desarrollando en un sistema cerrado (es decir, en un sistema integrado de Windows CE) y refactorizar la biblioteca sería difícil y llevaría mucho tiempo.

  • Gran pregunta, me ocupé de esto yo mismo hace más de 2 años.

    – Matt Carpintero

    21/10/2010 a las 20:25

avatar de usuario
Steve Townsend

Utilizar _fileno seguido por _get_osfhandle. no te olvides de _close cuando hayas terminado.

EDITO: no me queda claro que _get_osfhandle es compatible con WinCE. Sin embargo, los documentos para WinCE _fileno digamos que devuelve un “identificador de archivo” en lugar de un “descriptor”. YMMV pero esto sugiere que quizás puedas usar _fileno devuelve el valor directamente como un identificador en WinCE.

EDITAR: # 2 Esa teoría está respaldada por la experiencia de esta persona.

“Si echa un vistazo a los archivos de encabezado que publiqué en la lista el 29 de enero, puede ver cómo manejé el problema de creación/manejo de archivos. No tuve que reemplazar todos los elementos FILE* con HANDLE. Consulte 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. Solo tienes que lanzarlo”.

  • 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.

    – Lornova

    21 de octubre de 2010 a las 17:54

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

Sin embargo, no sé si se aplica a Windows y devuelve el MANGO.

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

    – Lornova

    21 de octubre de 2010 a las 16:28

  • Es solo una función de compatibilidad para * nix. Los identificadores tienen el tamaño de un puntero, 8 bytes en Win64.

    -Hans Passant

    21 de octubre de 2010 a las 16:53

avatar de usuario
zombo

Para C, prueba esto

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

  • Usado más tarde, esto me dice que el identificador no es válido para, por ejemplo, stdout.

    – imallet

    17 dic 2016 a las 19:39

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad