为ffi运行hs_init(0,0)时出现分段错误

时间:2013-01-10 15:37:23

标签: haskell ffi

我试图从python调用Haskell函数。 我有以下make文件:

GHC=ghc
GHC_RUNTIME_LINKER_FLAG=-lHSrts-ghc7.4.1

libffi-example.so: Example.o wrapper.o
    $(GHC) -o $@ -shared -dynamic -fPIC $^ $(GHC_RUNTIME_LINKER_FLAG)

Example_stub.h Example.o: Example.hs
    $(GHC) -c -dynamic -fPIC Example.hs

wrapper.o: wrapper.c Example_stub.h
    $(GHC) -c -dynamic -fPIC wrapper.c

clean:
    rm -f *.hi *.o *_stub.[ch]

clean-all:
    rm -f *.hi *.o *_stub.[ch] *.so


# Runs the example Python program
example: libffi-example.so
    python program.py

唯一的东西是wrapper.c通过调用hs_iniths_init(0,0);创建包装器。包装器称为example_init

我在make example中运行example_init时遇到分段错误(即在调用hs_init(0,0)时)。

有人可以告诉我为什么会这样做和/或如何修复它?

谢谢!

1 个答案:

答案 0 :(得分:2)

它应该工作:

  

“此外,对于argc和argv,可以使用NULL调用hs_init(),表示缺少命令行参数。”

这似乎是ghc-7.2.1到ghc-7.4.1的错误:

<强> RFib.hs:

{-# LANGUAGE ForeignFunctionInterface #-}
module RFib where

fib :: Int -> Int
fib n
    | n >= 0    = go 0 1 n
    | even n    = -go 0 1 (-n)
    | otherwise = go 0 1 (-n)
      where
        go a _ 0 = a
        go a b k = go b (a+b) (k-1)

foreign export ccall "rfib" fib :: Int -> Int

<强> rfib.c:

#include <stdio.h>
#include <HsFFI.h>

int rfib(int);

int main(void) {
    hs_init(0,0);
    printf("%d\n", rfib(35));
    hs_exit();
    return 0;
}

编译并运行:

$ rm rfib.o RFib.hi RFib.o a.out
$ ghc-7.0.2 -O2 -Wall -no-hs-main RFib.hs rfib.c && ./a.out
[1 of 1] Compiling RFib             ( RFib.hs, RFib.o )
Linking a.out ...
9227465
$ rm rfib.o RFib.hi RFib.o a.out
$ ghc-7.0.4 -O2 -Wall -no-hs-main RFib.hs rfib.c && ./a.out
[1 of 1] Compiling RFib             ( RFib.hs, RFib.o )
Linking a.out ...
9227465
$ rm rfib.o RFib.hi RFib.o a.out
$ ghc-7.2.1 -O2 -Wall -no-hs-main RFib.hs rfib.c && ./a.out
[1 of 1] Compiling RFib             ( RFib.hs, RFib.o )
Linking a.out ...
Speicherzugriffsfehler
$ rm rfib.o RFib.hi RFib.o a.out
$ ghc-7.2.2 -O2 -Wall -no-hs-main RFib.hs rfib.c && ./a.out
[1 of 1] Compiling RFib             ( RFib.hs, RFib.o )
Linking a.out ...
Speicherzugriffsfehler
$ rm rfib.o RFib.hi RFib.o a.out
$ ghc-7.4.1 -O2 -Wall -no-hs-main RFib.hs rfib.c && ./a.out
[1 of 1] Compiling RFib             ( RFib.hs, RFib.o )
Linking a.out ...
Speicherzugriffsfehler
$ rm rfib.o RFib.hi RFib.o a.out
$ ghc-7.4.2 -O2 -Wall -no-hs-main RFib.hs rfib.c && ./a.out
[1 of 1] Compiling RFib             ( RFib.hs, RFib.o )
Linking a.out ...
9227465
$ rm rfib.o RFib.hi RFib.o a.out
$ ghc -O2 -Wall -no-hs-main RFib.hs rfib.c && ./a.out
[1 of 1] Compiling RFib             ( RFib.hs, RFib.o )
Linking a.out ...
9227465

更改rfib.c中的两行:

int main(int argc, char *argv[]) {
    hs_init(&argc,&argv);

它适用于所有版本(&gt; =我已安装的7.0)。

所以要解决它

  • 通过&argc&argv
  • 升级GHC

是两种最明显的方式。