Haskell FFI导出的const注释

3

我正在将一个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< int > 进行操作)
inline int foo(const std::vector<int> &v)
{
  return foo(v.data(), v.size());
}

(不包括 const_cast。)

尝试手动更改头文件中的函数签名为 extern "C" HsInt32 foo(const HsPtr a1, HsInt32 a2); - army007
1
这将会得到期望的结果。然而,由于我正在生成头文件存根作为我的构建基础设施的一部分,我更愿意有一种直接在 .hs 文件中指定注释的方法。 - sekoenig
真的很烦人,我们在Haskell中无法在FFI声明中使用适当的const指针。你考虑过在GHC Trac上提交一个功能请求吗? - leftaroundabout
1个回答

2
GHC没有为生成带有const注释的C语言辅助函数提供功能。特别地,GHC源代码中相关代码位于compiler/deSugar/DsForeign.hs函数mkFExportCBits中,用于生成C stub。每个参数都被赋予一个不带装饰的C类型,包括前缀 "Hs" 和构造函数的名称。在这些位置中没有任何方法添加const。
甚至无法让GHC使用用户定义的C类型,例如HsConstPtr:外部参数所允许的类型受到boxedMarshalableTyCon函数(以及includes/HsFFI.h中C类型的关联定义)限制。
另一方面,在编写包装器时,你完全可以强制转换掉const,这一点也不清楚为什么会有问题。
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());
}

如果这让你感到不舒服......嗯,编程就是个肮脏的行业,对吧?

v2 是指 pv,还是反过来? - Davislor
1
谢谢!现在应该修好了。 - K. A. Buhr
2
实际上,我不喜欢使用肮脏的const_cast,但现在它被隐藏在HaskellPointer()包装函数中。我的希望是,也许在未来这个功能可以被删除 - 至少天真地认为,拥有像“ConstPtr a”类型这样的东西也可能有助于优化目的。就目前而言,感谢挖掘出当前在Haskell方面无法添加注释的事实! - sekoenig

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接