2012-01-11 17 views
6

से Haskell पुस्तकालयों का आयात करता है के एक आम उदाहरण लेते हैं कि कैसे एक haskell समारोह एक सी समारोह से कहा जा सकता है:GHC/FFI: बुला 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 

और सी मॉड्यूल :

#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 

यह ठीक है। लेकिन अगर मुझे हैकेल मॉड्यूल में कुछ लाइब्रेरी आयात करने की ज़रूरत है तो क्या होगा? उदाहरण के लिए, अगर मैं bytestrings मैं "आयात 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 का उपयोग के रूप में, मैं पहले से ही इस सुविधा को लागू किया है। इसलिए मुझे नहीं पता कि समस्या को कैसे ठीक किया जाए।

शायद, साझा लाइब्रेरी बनाना और गतिशील रूप से इसे मेरे सी मॉड्यूल से लिंक करना आसान होगा?

+1

परिवर्तन 6.12.3 से नया है, इसलिए आपको अभी भी 6.12 के साथ 'hs_add_root' को कॉल करना होगा। यह इसे 7.0 में भी नहीं बना था। –

उत्तर

4

मुझे नहीं लगता कि बग संबंधित है। क्या आपने --make का उपयोग करने का प्रयास किया है?

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

उन त्रुटियों कर रहे हैं त्रुटियों के प्रकार आप --make का उपयोग किए बिना पैकेज निर्भरता के साथ शुद्ध-हास्केल कोड जोड़ने जब प्राप्त करने के लिए इस्तेमाल किया; डिफ़ॉल्ट रूप से base में जीएचसी लिंक, लेकिन यदि आप किसी अन्य पैकेज से कुछ भी चाहते हैं जो काम नहीं करता है।

तुम भी अगर आप एक अधिक "मैन्युअल" विधि चाहते हैं स्पष्ट रूप से संकुल निर्दिष्ट करने का प्रयास कर सकते हैं:

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

GHC 7 के बाद से, --make डिफ़ॉल्ट किया गया है।

+0

धन्यवाद, यह वही है जो मुझे चाहिए, इतना आसान :) और मैंने इसे जोड़ने का प्रयास करने में कई घंटे बर्बाद कर दिए हैं। – skvadrik

+0

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

+0

मैंने कामकाजी आदेशों के साथ अपना उत्तर अपडेट किया है :) – ehird

संबंधित मुद्दे