c - studio - ¿Hay un equivalente de Windows para fdopen para HANDLEs?
visual studio code para c (1)
Desafortunadamente, HANDLE s son bestias completamente diferentes de FILE* sy descriptores de archivos. En última instancia, el CRT maneja los archivos en términos de HANDLE y asocia esos HANDLE a un descriptor de archivo. Esos descriptores de archivo a su vez retrocede el puntero de estructura por FILE* .
Afortunadamente, hay una sección en esta página MSDN que describe las funciones que "proporcionan una forma de cambiar la representación del archivo entre una estructura FILE , un descriptor de archivo y un identificador de archivo Win32":
_fdopen,_wfdopen: asocia una secuencia con un archivo que se abrió previamente para E / S de bajo nivel y devuelve un puntero a la secuencia abierta._fileno: Obtiene el descriptor de archivo asociado a una secuencia._get_osfhandle: devolver el identificador de archivo del sistema operativo asociado con el descriptor de archivo C en tiempo de ejecución existente_open_osfhandle:_open_osfhandlearchivo de tiempo de ejecución de Associates C con un identificador de archivo de sistema operativo existente.
Parece que lo que necesitas es _open_osfhandle seguido de _fdopen para obtener un FILE* de un HANDLE .
Aquí hay un ejemplo de HANDLE s obtenido de CreateFile() . Cuando lo probé, muestra los primeros 255 caracteres del archivo "test.txt" y agrega "--- Hello World! ---" al final del archivo:
#include <windows.h>
#include <io.h>
#include <fcntl.h>
#include <cstdio>
int main()
{
HANDLE h = CreateFile("test.txt", GENERIC_READ | GENERIC_WRITE, 0, 0,
OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
if(h != INVALID_HANDLE_VALUE)
{
int fd = _open_osfhandle((intptr_t)h, _O_APPEND | _O_RDONLY);
if(fd != -1)
{
FILE* f = _fdopen(fd, "a+");
if(f != 0)
{
char rbuffer[256];
memset(rbuffer, 0, 256);
fread(rbuffer, 1, 255, f);
printf("read: %s/n", rbuffer);
fseek(f, 0, SEEK_CUR); // Switch from read to write
const char* wbuffer = " --- Hello World! --- /n";
fwrite(wbuffer, 1, strlen(wbuffer), f);
fclose(f); // Also calls _close()
}
else
{
_close(fd); // Also calls CloseHandle()
}
}
else
{
CloseHandle(h);
}
}
}
Esto debería funcionar también para tuberías.
En Unix, si tiene un descriptor de archivo (por ejemplo, desde un socket, pipe o hereditario de su proceso principal), puede abrir un flujo de E / S FILE* en fdopen(3) con fdopen(3) .
¿Hay un equivalente en Windows para HANDLE s? Si tiene un HANDLE que se heredó de su proceso principal (diferente de stdin, stdout o stderr) o un conducto de CreatePipe , ¿es posible obtener un flujo de FILE* almacenado en él? MSDN documenta _fdopen , pero funciona con descriptores de archivos enteros devueltos por _open , no _open genéricas.