c - GHC/FFI : calling haskell module which imports haskell libraries from C

标签 c haskell import ffi

让我们举一个如何从 C 函数调用 haskell 函数的常见示例:

Haskell 模块:

{-# LANGUAGE ForeignFunctionInterface #-}

module Safe where

import Foreign.C.Types

fibonacci :: Int -> Int
fibonacci n = fibs !! n
    where fibs = 0 : 1 : zipWith (+) fibs (tail fibs)

fibonacci_hs :: CInt -> CInt
fibonacci_hs = fromIntegral . fibonacci . fromIntegral

foreign export ccall fibonacci_hs :: CInt -> CInt

和C模块:

#include <HsFFI.h>
#ifdef __GLASGOW_HASKELL__
#include "Safe_stub.h"
extern void __stginit_Safe(void);
#endif
#include <stdio.h>

int main(int argc, char *argv[]) {
   int i;
   hs_init(&argc, &argv);
#ifdef __GLASGOW_HASKELL__
   hs_add_root(__stginit_Safe);
#endif

   i = fibonacci_hs(42);
   printf("Fibonacci: %d\n", i);

   hs_exit();
   return 0;
}

我编译并链接它:

$ ghc -c -O Safe.hs
$ ghc test.c Safe.o Safe_stub.o -o test

没关系。但是如果我需要在 haskell 模块中导入一些库怎么办?例如,如果我需要使用 bytestrings,我应该添加“import Data.Bytestring.Char8”(此模块仅作为示例,未在代码中使用):

{-# LANGUAGE ForeignFunctionInterface #-}

module Safe where

import Foreign.C.Types
import Data.Bytestring.Char8

fibonacci :: Int -> Int
fibonacci n = fibs !! n
    where fibs = 0 : 1 : zipWith (+) fibs (tail fibs)

fibonacci_hs :: CInt -> CInt
fibonacci_hs = fromIntegral . fibonacci . fromIntegral

foreign export ccall fibonacci_hs :: CInt -> CInt

那不行,现在我得到一个错误:

$ ...undefined reference to `__stginit_bytestringzm0zi9zi2zi0_DataziByteStringziChar8_'

我目前发现的问题是: a bug in GHC如下 changeset (more formal description of the bug)

当我使用 ghc-6.12.3 时,我已经实现了这个功能。所以我不知道如何解决这个问题。

也许,创建一个共享库并将其动态链接到我的 C 模块会更容易?

最佳答案

我不认为这个错误是相关的。您是否尝试过使用 --make

$ ghc -c -O Safe.hs
$ ghc --make test.c Safe.o Safe_stub.o -o test

这些错误是您在不使用 --make 的情况下将纯 Haskell 代码与包依赖项链接时遇到的错误类型1;默认情况下,GHC 链接在 base 中,但如果您想要来自其他包的任何内容,则该链接不起作用。

如果您想要更“手动”的方法,您也可以尝试明确指定包:

$ ghc -c -O Safe.hs
$ ghc -package bytestring test.c Safe.o Safe_stub.o -o test

1 自 GHC 7 以来,--make 已成为默认值。

关于c - GHC/FFI : calling haskell module which imports haskell libraries from C,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8822311/

相关文章:

haskell - 无积分等值

haskell - 使用 Writer monad 写入文件时如何避免内存问题?

grails - Grails JFreeChart无法解析类:org.jfree.chart.ChartFactory

c - 递归函数在C中返回0

haskell - 延续的正确术语

java - 不确定将类作业所需的 Java 库放在哪里

android - 错误 :Newer :Execution failed for task ':app:dexDebug' . com.android.ide.common.process.ProcessException

c++ - 将变量放置在绝对内存位置 (IAR C/C++)

c - 为什么使用不在 UB 范围内的标识符而不是错误

c - Debian 中 gcc 的奇怪行为