2012-01-11 27 views
6

gelen haskell kütüphaneleri ithal çağıran haskell modülü haskell işlevi, bir C işlevi çağrılabilir nasıl en yaygın örneği ele alalım:GHC/FFI: C

Haskell modülü:

{-# 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 

Ve C modülü :

#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; 
} 

ben derlemek ve bağlamak:

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

Tamam. Ama eğer bazı kütüphaneleri haskell modülüne aktarmam gerekirse? Ben "ithal Data.Bytestring.Char8" eklemek gerekir bytestrings kullanmanız gerekiyorsa Örneğin, (bu modül bir örnek için alınır ve kod kullanılmamaktadır):

{-# 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 

Ve bu şimdi, tamam değil ben bir hata alıyorum:

$ ...undefined reference to `__stginit_bytestringzm0zi9zi2zi0_DataziByteStringziChar8_' 

Tüm Şu anda problem üzerinde bulduk şudur: a bug in GHC ve ben ghc-6.12.3 kullanıldıkça changeset (more formal description of the bug)

aşağıdaki gibi, zaten uygulanan bu özellik vardır. Bu yüzden sorunu nasıl çözeceğimi bilmiyorum.

Belki de paylaşılan bir kitaplık oluşturmak ve C modülüm ile dinamik olarak bağlamak daha kolay olurdu.

+1

Değişiklik kümesi 6.12.3'ten daha yeni, bu nedenle 6.12 ile hs_add_root'unu çağırmanız gerekiyor. Onu 7.0'a bile getirmedi. –

cevap

4

Bu hatanın alakalı olduğunu sanmıyorum. --make kullanmayı denediniz mi?

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

olanlar hatalar hataları türlü mı 1--make kullanmadan paket bağımlılıkları ile saf-Haskell kodu bağlarken almak için kullanılır; GHC bağlantıları varsayılan olarak base'dadır, ancak çalışmayan başka bir paketten herhangi bir şey istiyorsanız.

Eğer daha "el" yöntemi istiyorsanız da açıkça paketleri belirterek deneyebilirsiniz: ghc 7 beri --make varsayılan olmuştur

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

.

+0

Teşekkür ederim, bu tam olarak ihtiyacım olan şey, çok basit :) Ve bağlantı kurmaya çalışırken çok zaman harcadım. – skvadrik

+0

$ ghc -c -O Güvenli.hs' $ ghc -package bytestring sınama.c Güvenli.o Safe_stub.o -o test' – skvadrik

+0

Cevabımı çalışma komutları ile güncelledim :) – ehird