visual studio para depurar create configurar compiler compilar codigo code c winapi stdio

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_osfhandle archivo 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.