2

我正在尝试从 python 调用 Haskell 函数。我有以下制作文件:

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_init通过调用创建包装器hs_init(0,0);。包装器被称为example_init

make example运行时example_init(即调用时)出现分段错误hs_init(0,0)

有人能告诉我为什么会这样和/或如何解决吗?

谢谢!

4

1 回答 1

2

它应该工作:

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

这似乎是 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);

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

所以要修复它

  • 通过&argc&argv
  • upgrade GHC

are the two most obvious ways.

于 2013-01-10T17:57:27.770 回答