|Version 16 (modified by 7 years ago) (diff),|
Foreign Function Interface
The Foreign Function Interface (FFI) adds support for invoking code and accessing data structures implemented in other programming languages and vice versa. The current proposal encompasses a general mechanism for inter-language operations as well as specific support for interoperating with the C programming language.
- Widely accepted and used addendum.
- Provides an essential facility.
- Inappropriate use can subvert all semantic guarantees provided by Haskell and can cause memory corruption and program crashes.
The following topics still require a bit of discussion or a decision between multiple alternatives.
A large part of the FFI addendum are the libraries living under
Foreign in the library hierarchy. Given the general discussion surrounding the inclusion of libraries into Haskell', we need a concrete approach for the
Foreign libraries. A tentative proposal was the following:
- The FFI addendum has been written before the proposal for HierarchicalModules, it uses a flat names space. In Haskell', we will use the hierarchical names from the standard library.
- Haskell' keeps a subset of the libraries defined by Haskell 98 (but with their hierarchical names) and adds the FFI libraries.
TODO Decide whether we adopt the above tentative proposal.
The FFI addendum currently requires that
hs_exit() can be followed by another
hs_init(). GHC doesn't support that and I am not convinced that we should require it. I propose to remove that requirement.
TODO Decide whether we remove the requirement for re-initialisation.
It can be tedious to add include files to a large number foreign imports, which is why GHC users often use
-#include options instead. I am wondering whether we should add a form
foreign import "include FNAME"
We would still allow include files in other
foreign import statements as before, but would gain a portable version of
TODO Decide whether we want this addition.
Cross-platform libraries (e.g. HOpenGL) often want to import the same foreign functions using the
ccall convention on Unix and the
stdcall convention on Windows. The usual method is to use CPP hackery. Would there be any harm to implement
ccall on Unix? In other words, do we need
stdcall on Unix at all?
TODO Decide whether we allow implementations to implement
ccall if that is appropriate for the platform.
Integration into the report
The FFI addendum is already written and formatted in the style of the report — it should be straight forward to integrate. In addition the following changes relative to the original addendum will be applied.
Hierarchical names for the libraries
Changes to the library portion as discussed above under "Open Questions".
Transparent marshalling of newtypes
The FFI addendum defines in Section 3.2 that The argument types
ati produced by
fatype must be marshallable foreign types; that is, each
ati is either (1) a basic foreign type or (2) a type synonym or renamed datatype of a marshallable foreign type. We will improve on the second part of this statement as follows:
- As the transparent marshalling of newtypes (aka renamed datatypes) is a fairly significant features, we will dedicate a separate (sub)subsection to it.
- In contrast to the FFI addendum (and it's implementation in GHC), we require that a newtype in a foreign signature is not abstract. Only if its constructor is visible, can the newtype be transparently marshalled. (After all, marshalling makes only sense if we know the type of the value in foreign land.) This implies that we will export the newtypes in the modules
- Clarify the connection between marshallable foreign types and the various flavours of foreign signatures discussed in Section 4.1.3. (E.g., in case of a
foreign import "dynamic"the whole signature —grammar nonterminal
ftype— doesn't need to be marshallable, only portions of it.)
- We allow GHC's newtype wrapping of the IO monad.
- We add one or two examples.
Changes to the FFI libraries
- We should also have
castCSCharToChar(i.e., not only for CChar of which it is platform-dependent whether it is signed or not).
- Types from ISO C99 (with conversion routines):
WordPtr uintptr_t WordMax uintmax_t IntPtr intptr_t IntMax intmax_t ptrToWordPtr :: Ptr a -> WordPtr wordPtrToPtr :: WordPtr -> Ptr a ptrToIntPtr :: Ptr a -> IntPtr intPtrToPtr :: IntPtr -> Ptr a