Как мне получить файл HANDLE из структуры fopen FILE? - PullRequest
26 голосов
/ 21 октября 2010

Функция <a href="http://msdn.microsoft.com/en-us/library/yeby3zcb.aspx" rel="noreferrer">fopen</a> возвращает указатель на структуру FILE, которая должна рассматриваться как непрозрачное значение, без учета его содержимого или значения.

В Windows среда выполнения C является оболочкой API Windows, а функция fopen основана на функции <a href="http://msdn.microsoft.com/en-us/library/aa363858(VS.85).aspx" rel="noreferrer">CreateFile</a>. Функция CreateFile возвращает HANDLE, который используется другим API Windows.

Теперь мне нужно использовать Windows API глубоко внутри библиотеки, которая использует fopen и FILE*. Итак: есть ли способ получить HANDLE из структуры FILE? Поскольку это зависит от компилятора, я имею в виду библиотеку времени выполнения MSVC.

Я понимаю, что это был бы уродливый, непереносимый хак, и он может сломаться, если Microsoft изменит внутренний формат FILE ... но я занимаюсь разработкой на закрытой системе (т.е. на встроенной Windows CE система), и рефакторинг библиотеки будет трудным и трудоемким.

Ответы [ 3 ]

15 голосов
/ 21 октября 2010

Используйте _fileno, а затем _get_osfhandle. Не забудьте _close, когда закончите.

РЕДАКТИРОВАТЬ: мне не ясно, что _get_osfhandle поддерживается в WinCE. Однако документы для WinCE _fileno говорят, что он возвращает «дескриптор файла», а не «дескриптор». YMMV, но это говорит о том, что вы можете просто использовать _fileno возвращаемое значение непосредственно в качестве дескриптора на WinCE.

РЕДАКТИРОВАТЬ: # 2 Эта теория подтверждается опыт этого человека .

"Если вы посмотрите на файлы заголовков, которые я опубликовал в списке 29 января Вы можете увидеть, как я справился с проблемой создания / обработки файлов. У меня не было заменить все элементы FILE * на РУЧКИ. Смотрите следующий фрагмент из 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

Оказывается, _fileno возвращает дескриптор. Вам просто нужно разыграть его. "

5 голосов
/ 21 октября 2010

В Linux есть функция int fileno(FILE *);, которая возвращает дескриптор файла (тот, который был возвращен низкоуровневой функцией open) из FILE*.

Я не знаюесли это относится к Windows и возвращает РУЧКУ, хотя?

3 голосов
/ 30 июля 2012

Для C попробуйте это

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