通过GHC的FFI传递字节阵列类型之一意味着什么?



在 Haskell2010 报告中,从第 8.4.2 节开始,列出了 FFI 进出口申报中支持的基本类型:

以下类型构成了一组基本的外来类型:

  • CharIntDoubleFloatBool,由哈斯克尔前奏
  • 曲以及
  • Int8Int16Int32Int64Word8Word16Word32Word64Ptr aFunPtr aStablePtr a,适用于任何类型的a,如国外出口 (第24节)。

实现FFI的Haskell系统需要能够通过 Haskell和外部上下文之间的这些类型作为函数 参数和结果。

在 GHC 手册中有关 FFI 扩展的部分,GHC 通过一些未装箱的类型添加到这些类型中:

以下未装箱类型可用作基本外来类型(请参阅 FFI 附录,第 3.2 节):Int#Word#Char#Float#Double#Addr#StablePtr# aMutableByteArray#ForeignObj#ByteArray#

当我指定ccall调用约定时,很明显在链接器级别上大多数这些类型会发生什么。例如,我很确定Int/Int#作为两个 32 位值在堆栈上传递。同样,Ptr a/StablePtr a/StablePtr# a/Addr#可能都作为堆栈上的指针传递。

ByteArray#MutableByteArray#呢?

我所能想象的就是将它们作为指针传递,但这似乎有点疯狂,因为除非您将ByteArray#/MutableByteArray#固定,否则 GHC 运行时最终可能会从您下方移动数组。此外,您还将忽略数组上的大小信息。

感谢 @ThomasM.DuBuisson 挖掘出一个旧的电子邮件线程:

有一种方法可以通过未固定的ByteArray#(或MutableByteArray#, 但前者在您的情况下似乎是正确的)拨打外国电话,使用UnliftedFFITypes语言扩展。ByteArray#保证 在通话期间不移动。代码应处理ByteArray#参数,就好像它是指向字节的指针一样。您将需要 在 C 端进行任何地址偏移计算(即传递任何 偏移量作为 C 函数的额外参数)。

所以:这些是作为指针传递的,GHC 的运行时承诺不会将它们从你下面移动。

相关内容

  • 没有找到相关文章

最新更新