24

Is there easy way to create FILE* from WinApi HANDLE which points to one end of pipe? Something like we do in unix: fdopen(fd,<mode>);

Mihran Hovsepyan
  • 10,450
  • 13
  • 59
  • 110

3 Answers3

30

You can do this but you have to do it in two steps. First, call _open_osfhandle() to get a C run-time file descriptor from a Win32 HANDLE value, then call _fdopen() to get a FILE* object from the file descriptor.

George Sovetov
  • 4,474
  • 5
  • 31
  • 55
Greg Hewgill
  • 890,778
  • 177
  • 1,125
  • 1,260
  • 1
    Does those function take ownership of the underlying handle, or should CloseHandle still be called? – user877329 Nov 13 '14 at 09:11
  • @user877329: I think you still need to call `CloseHandle()`, but it would be worth checking. It's been quite some time since I have used those functions. The Microsoft runtime library source code comes with the compiler so you can write a test program and trace it to check. – Greg Hewgill Nov 13 '14 at 16:17
4
FILE* getReadBinaryFile(LPCWSTR path) {
    HANDLE hFile = CreateFile(path, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    if (hFile == INVALID_HANDLE_VALUE) { 
        return nullptr; 
    }
    int nHandle = _open_osfhandle((long)hFile, _O_RDONLY);
    if (nHandle == -1) { 
        ::CloseHandle(hFile);   //case 1
        return nullptr; 
    }
    FILE* fp = _fdopen(nHandle, "rb");
    if (!fp) {
        ::CloseHandle(hFile);  //case 2
    }
    return fp;
}

my code for get an open read binary file descriptor.

you should use fclose to close FILE* if you don't need it .

i didn't test for case 1 and 2, so use it at your own risk.

max zhou
  • 43
  • 3
-1

you can't exchange(convert) them.. if you need to have a file with FILE* and HANDLE you need to open it twice

fazo
  • 1,832
  • 12
  • 15