通过 GHC 的 FFI 传递一种 ByteArray 类型是什么意思?
What does it mean to pass one of the ByteArray types through GHC's FFI?
在 Haskell2010 报告中,来自 section 8.4.2,有一个 FFI import/export 声明支持的基本类型列表:
The following types constitute the set of basic foreign types:
Char
, Int
, Double
, Float
, and Bool
as exported by the Haskell Prelude as well as
Int8
, Int16
, Int32
, Int64
, Word8
, Word16
, Word32
, Word64
, Ptr a
, FunPtr a
, and StablePtr a
, for any type a
, as exported by Foreign
(Section 24).
A Haskell system that implements the FFI needs to be able to pass
these types between the Haskell and the external context as function
arguments and results.
来自 GHC 手册关于 FFI 扩展的部分,GHC adds to these types with some unboxed types:
The following unboxed types may be used as basic foreign types (see
FFI Addendum, Section 3.2): Int#
, Word#
, Char#
, Float#
,
Double#
, Addr#
, StablePtr# a
, MutableByteArray#
,
ForeignObj#
, and ByteArray#
.
很清楚,当我指定 ccall
调用约定时,大多数这些类型在链接器级别会发生什么。例如,我很确定 Int
/Int#
作为两个 32 位值在堆栈上传递。同样,Ptr a
/StablePtr a
/StablePtr# a
/Addr#
可能都作为堆栈上的指针传递。
ByteArray#
和MutableByteArray#
呢?
我所能想象的就是将它们作为指针传递,但这似乎有点疯狂,因为除非您使 ByteArray#
/MutableByteArray#
固定,否则 GHC 运行时可能最终会将数组从在你之下。此外,您还会忽略数组中的大小信息。
感谢@ThomasM.DuBuisson 挖掘 old email thread:
There is a way to pass an unpinned ByteArray#
(or MutableByteArray#
,
but the former seems right in your case) to a foreign call, using the
UnliftedFFITypes
language extension. The ByteArray#
is guaranteed to
not to be moved for the duration of the call. The code should treat
the ByteArray#
argument as if it was a pointer to bytes. You will need
to do any address offset computations on the C side (i.e. pass any
offsets you need as extra argument to your C function).
因此:这些作为指针传递,GHC 的运行时承诺不会将它们从您的下方移动。
在 Haskell2010 报告中,来自 section 8.4.2,有一个 FFI import/export 声明支持的基本类型列表:
The following types constitute the set of basic foreign types:
Char
,Int
,Double
,Float
, andBool
as exported by the Haskell Prelude as well asInt8
,Int16
,Int32
,Int64
,Word8
,Word16
,Word32
,Word64
,Ptr a
,FunPtr a
, andStablePtr a
, for any typea
, as exported by Foreign (Section 24).A Haskell system that implements the FFI needs to be able to pass these types between the Haskell and the external context as function arguments and results.
来自 GHC 手册关于 FFI 扩展的部分,GHC adds to these types with some unboxed types:
The following unboxed types may be used as basic foreign types (see FFI Addendum, Section 3.2):
Int#
,Word#
,Char#
,Float#
,Double#
,Addr#
,StablePtr# a
,MutableByteArray#
,ForeignObj#
, andByteArray#
.
很清楚,当我指定 ccall
调用约定时,大多数这些类型在链接器级别会发生什么。例如,我很确定 Int
/Int#
作为两个 32 位值在堆栈上传递。同样,Ptr a
/StablePtr a
/StablePtr# a
/Addr#
可能都作为堆栈上的指针传递。
ByteArray#
和MutableByteArray#
呢?
我所能想象的就是将它们作为指针传递,但这似乎有点疯狂,因为除非您使 ByteArray#
/MutableByteArray#
固定,否则 GHC 运行时可能最终会将数组从在你之下。此外,您还会忽略数组中的大小信息。
感谢@ThomasM.DuBuisson 挖掘 old email thread:
There is a way to pass an unpinned
ByteArray#
(orMutableByteArray#
, but the former seems right in your case) to a foreign call, using theUnliftedFFITypes
language extension. TheByteArray#
is guaranteed to not to be moved for the duration of the call. The code should treat theByteArray#
argument as if it was a pointer to bytes. You will need to do any address offset computations on the C side (i.e. pass any offsets you need as extra argument to your C function).
因此:这些作为指针传递,GHC 的运行时承诺不会将它们从您的下方移动。