#winapi #haskell #io
#winapi #хаскелл #io #haskell
Вопрос:
Я хочу создать анонимный канал в Windows, используя CreatePipe
WinAPI через FFI. Это даст мне HANDLE
(тип из Win32
пакета haskell), но я хотел бы получить обычный haskell Handle
, чтобы я мог использовать на нем стандартные функции ввода-вывода haskell. Итак, мне нужна функция типа:
win32handleToStandardHandle :: HANDLE -> IO Handle
Как я могу это реализовать?
В Linux я могу использовать System.Posix.IO
fdToHandle
функцию для преобразования между FD
типом, используемым системными вызовами Linux, и стандартным типом haskell. Но, похоже, такой функции для Windows нет.
Комментарии:
1. Похоже, что
HANDLE
это просто синоним типа:type HANDLE = Ptr ()
. Я понятия не имею, как ответить на ваш вопрос, но это не дает функции преобразования особых возможностей для работы… :2. Я вижу, что
HANDLE
определяется какtype HANDLE = Ptr ()
, в то время какHandle
является алгебраическим типом данных, представляющим либо одиночный дескриптор, либо дуплексный дескриптор для RW, который сам по себе реализуется сложной структурой записи. Существует ли много функций для получения информации оHANDLE
изWin32
API? Вам понадобятся такие вещи, как режим буферизации, текущий буфер символов, кодировка текста и т.д. Возможно, это можно написать самостоятельно, но я бы предположил, что исправление может быть несколько утомительным.
Ответ №1:
Даже в Windows стандартная реализация файлов в System.IO
использует дескриптор файла, а не win32 HANDLE
. Эти файловые дескрипторы предоставляются средой выполнения C, а не Windows. Для преобразования HANDLE
в файловый дескриптор среда выполнения предоставляет _open_osfhandle
функцию. GHC использует MinGW в Windows, но MinGW не предоставляет собственную среду выполнения C, поэтому Haskell EXEs использует msvcrt.dll .
Используйте FFI для импорта _open_osfhandle
. Используйте это, чтобы преобразовать ваш HANDLE
в файловый дескриптор, а затем вызвать fdToHandle
, который, похоже, находится в GHC.IO.Handle.FD
.
На самом деле я этого не пробовал.
Комментарии:
1. MinGW не предоставляет собственную среду выполнения C, не так ли? Большинство людей, похоже, ссылаются на (неподдерживаемый!) msvcrt.dll , таким образом, документы MS настолько близки, насколько вы собираетесь получить.
2. @HarryJohnston Ты прав. Haskell EXEs импортирует стандартные функции C из msvcrt.dll .
3. Вы правы, что
fdToHandle
живет вGHC.IO.Handle.FD
. Однако он принимает аргумент типаFD
, который определен в недоступном модулеGHC.IO.FD
. Но, как вы говорите,HANDLE
функции ввода-вывода GHC на самом деле не поддерживаются, поэтому я просто напишу функции чтения / записи напрямую дляHANDLE
, это намного проще.4. @bennofs Есть два разных типа, которые называются
FD
. Незащищенный вариант несколько сложен, ноfdToHandle
используетSystem.Posix.Internals.FD
всего лишьCInt
.5. @bennofs: обратите внимание, что у каждого
Handle
есть связанныйHANDLE
, потому что без него процесс фактически не может выполнять какие-либо операции ввода-вывода. Единственное отличие здесь в том, что вы хотите использоватьHANDLE
, который вы открыли сами, а не тот, который Haskell (и среда выполнения C) открыли для вас.