【问题标题】:Convert HANDLE to Handle将 HANDLE 转换为句柄
【发布时间】:2014-07-02 19:12:27
【问题描述】:

我想通过 FFI 使用 WinAPI 的 CreatePipe 在 Windows 上创建一个匿名管道。这将给我一个HANDLE(来自Win32 haskell 包的类型),但我想获得一个普通的haskell Handle,这样我就可以在其上使用标准的haskell IO 函数。所以我需要一个类型的函数:

win32handleToStandardHandle :: HANDLE -> IO Handle

我该如何实现?

在linux上,我可以使用System.Posix.IOfdToHandle函数在linux系统调用使用的FD类型和标准haskell类型之间进行转换。但是windows似乎没有这样的功能。

【问题讨论】:

  • 看起来HANDLE 只是一个类型同义词:type HANDLE = Ptr ()。我不知道如何回答你的问题,但这并没有给转换函数带来太多的工作......:\
  • 我可以看到HANDLE被定义为type HANDLE = Ptr (),而Handle是一个代数数据类型,代表RW的单句柄或双工句柄,它本身是由一个复杂的记录结构。是否有许多函数可以从Win32 API 获取有关HANDLE 的信息?您将需要诸如缓冲模式、当前字符缓冲区、文本编码等内容。您可以自己编写,但我想正确可能会有些乏味。

标签: winapi haskell io


【解决方案1】:

即使在 Windows 上,System.IO 中文件的标准实现也使用文件描述符,而不是 win32 HANDLE。这些文件描述符由 C 运行时提供,而不是 Windows。要将HANDLE 转换为文件描述符,运行时提供了_open_osfhandle 函数。 GHC 在 Windows 上使用 MinGW,但 MinGW 不提供自己的 C 运行时,因此 Haskell EXE 使用 msvcrt.dll。

使用 FFI 导入 _open_osfhandle。使用它来将您的HANDLE 转换为文件描述符,然后调用fdToHandle,它似乎存在于GHC.IO.Handle.FD 中。

我还没有真正尝试过。

【讨论】:

  • MinGW 不提供自己的 C 运行时,是吗?大多数人似乎都链接到(不受支持!)msvcrt.dll,因此 MS 文档与您将获得的一样接近。
  • @HarryJohnston 你是对的。 Haskell EXE 从 msvcrt.dll 导入 C 的标准函数。
  • 你说得对,fdToHandle 住在GHC.IO.Handle.FD。但是,它采用FD 类型的参数,该参数在非公开模块GHC.IO.FD 中定义。但是正如你所说,GHC IO 函数并不真正支持HANDLE,所以我将直接为HANDLE 编写读/写函数,这样会容易得多。
  • @bennofs 有两种不同的类型,称为FD。未暴露的有点复杂,但fdToHandle 使用的是System.Posix.Internals.FD,它只是一个CInt
  • @bennofs:请注意,每个Handle 都有一个关联的HANDLE,因为没有一个,进程实际上无法进行任何 I/O。这里唯一的区别是您要使用自己打开的HANDLE,而不是 Haskell(和 C 运行时)为您打开的 HANDLE
猜你喜欢
  • 1970-01-01
  • 2011-09-04
  • 1970-01-01
  • 1970-01-01
  • 2011-01-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多