在Haskell2010报告中,section 8.4.2中有一个FFI导入/导出声明支持的基本类型列表:
以下类型构成基本外来类型的集合:
Haskell Prelude导出的
Char
,Int
,Double
,Float
和Bool
以及Int8
,Int16
,Int32
,Int64
,Word8
,Word16
,Word32
,Word64
,Ptr a
,FunPtr a
和StablePtr a
,对于任何类型a
,由外国人导出 (第24节)。实现FFI的Haskell系统需要能够通过 Haskell和外部上下文之间的这些类型作为函数 论点和结果。
关于FFI扩展的GHC手册部分,GHC adds to these types with some unboxed types:
以下未装箱类型可用作基本外来类型(请参阅 FFI附录,第3.2节):
Int#
,Word#
,Char#
,Float#
,Double#
,Addr#
,StablePtr# a
,MutableByteArray#
,ForeignObj#
和ByteArray#
。
很明显,当我指定ccall
调用约定时,链接器级别的大多数类型会发生什么。例如,我非常确定Int
/ Int#
作为两个32位值在堆栈上传递。同样,Ptr a
/ StablePtr a
/ StablePtr# a
/ Addr#
可能全部作为堆栈指针传递。
ByteArray#
和MutableByteArray#
怎么样?
我能想象的只是将它们作为指针传递,但这似乎有点疯狂,因为除非你使ByteArray#
/ MutableByteArray#
固定,否则GHC运行时可能最终会从你下面移动数组。此外,您还将忽略阵列上的大小信息。
答案 0 :(得分:0)
感谢@ThomasM.DuBuisson挖掘old email thread:
有一种方法可以传递取消固定的
ByteArray#
(或MutableByteArray#
, 但前者似乎在你的情况下对外国电话,使用UnliftedFFITypes
语言扩展。保证ByteArray#
在通话期间不要移动。代码应该对待ByteArray#
参数,好像它是指向字节的指针。你会需要 在C侧进行任何地址偏移计算(即通过任何地址) 作为C函数的额外参数需要补偿。)
所以:这些是作为指针传递的,GHC的运行时承诺不会将它们从你身下移开。