【发布时间】:2013-05-13 00:16:17
【问题描述】:
我刚刚花了一周左右的时间研究如何从 C# 执行 C++ 代码,作为我日常工作的一部分。我们花了很长时间才弄清楚,但最终的解决方案相当简单。
现在我很好奇...从 C# 调用 Haskell 有多难? (注意:这是调用 Haskell 来自 C#,而不是相反。所以主要的可执行文件是 C#。)
如果真的很难,我不会打扰。但如果它相当容易,我可能不得不玩它......
基本上,我们编写了一些 C++ 代码。在 Windows 上它被编译成一个 DLL,在 Linux 上它被编译成一个共享对象 (*.so)。然后在 C# 方面,如果你试图传递任何重要的东西,你会做一个DllImport 并编写一些手动内存管理代码。 (例如,数组、字符串等)
我知道 GHC 应该支持在两个平台上构建共享库,但我不确定技术细节。导出内容的语法是什么,调用者必须先做一些特殊的事情来初始化 DLL 吗?
具体来说:假设存在一个函数foobar :: FilePath -> IO Int32。有人可以拼凑一个小草图显示:
- 我需要编写哪些 Haskell 声明才能将其暴露给外界。
- 如何告诉 GHC 构建一个独立的 DLL/SO 文件。
- 除了绑定
foobar本身的常规过程之外,调用者需要执行的任何特殊操作。
我不太担心 C# 端的实际语法;我想我或多或少对此感到困惑。
附:我确实简要地查看了hs-dotnet,但这似乎是特定于 Windows 的。 (即,不适用于 Mono,因此不适用于 Linux。)
【问题讨论】:
-
对于 FFI 绑定,您总是有一个计划 B,即“在 C 中编写一个瘦包装器”。大多数具有任何类型 FFI 的语言都可以与 C 互操作。
-
指针:来自 GHC 用户指南的第 4.13 和 8.2 章,haskell.org/haskellwiki/Calling_Haskell_from_C
-
GHC 似乎有一个关于 DLL 创建的章节:haskell.org/ghc/docs/latest/html/users_guide/win32-dlls.html 在 GHC 的最新版本中,这部分似乎也发生了变化。 (!)
-
请注意如何编译和链接 c/c++ 代码 (stackoverflow.com/questions/5829170/…)。我不知道这种效果是否会暴露在 .net/managed 代码上。
-
@Jonke 出于完全相同的原因,我们在将 C++ 链接到 C# 时获得了七种乐趣。我不知道这些东西是什么,但显然它是正确的关键......