Haskell FFI 导出的常量注释

const annotation for Haskell FFI exports

本文关键字:常量 注释 FFI Haskell      更新时间:2023-10-16

我将一个 Haskell 函数公开给 C/C++

foreign export ccall foo :: Ptr CInt -> CInt -> IO CInt
foo ptr len = do
  list <- peekArray (fromIntegral len) ptr
  -- run calculation based on list entries
  return result

导出函数的签名变为

HsInt32 foo(HsPtr a1, HsInt32 a2);

但是,由于数组没有被修改,我宁愿把它作为

HsInt32 foo(const HsPtr a1, HsInt32 a2);

有没有办法自动添加此注释?

(动机是我希望它在 std::vector 通过

inline int foo(const std::vector<int> &v)
{
  return foo(v.data(), v.size());
}

不包括const_cast。

GHC 中没有用于生成带有const注释的 C 帮助程序函数的工具。 特别是,GHC 源中的相关代码位于生成 C 存根的函数mkFExportCBits compiler/deSugar/DsForeign.hs中。 每个参数都被赋予一个由前缀"Hs"和构造函数名称组成的朴素的 C 类型。 无法在任何地方添加const

甚至没有希望让 GHC 使用用户定义的 C 类型,就像您可以使用的HsConstPtr:允许的外部参数类型仅限于由 compiler/typecheck/TcType.hs 中的 boxedMarshalableTyCon 函数确定的类型(在 includes/HsFFI.h 中具有 C 类型的相关定义(。

另一方面,目前还不清楚为什么你不能丢弃你正在编写的包装器中的常量:

inline int foo_wrapper(const std::vector<int> &v)
{
  std::vector<int> &v2 = const_cast<std::vector <int>&>(v);
  return foo_haskell(v2.data(), v2.size());
}

如果这让你觉得很脏...好吧,编程是一项肮脏的工作,对吧?