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

の2行を変更するrfib.c

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

すべてのバージョンで動作します(私がインストールした> = 7.0)。

だからそれを修正するには

  • パス&argc&argv
  • GHCをアップグレードする

2つの最も明白な方法です。

于 2013-01-10T17:57:27.770 に答える