2013-01-03 12 views
11

मैं सी में एक पुस्तकालय के लिए एक FFI मॉड्यूल जो पहले कुछ और है एक 1-समय, गैर रैत्रांत समारोह के नाम से जाना चाहता है बना रहा हूं। यह कॉल बेवकूफ है, लेकिन राज्यपूर्ण है, इसलिए मैं इसे हर हास्केल कॉल में बस कॉल कर सकता हूं। लेकिन यह धीमा है और गैर-पुनर्वितरण के कारण यह संघर्ष पैदा कर सकता है।unsafePerformIO और FFI पुस्तकालय प्रारंभ

तो यह सही समय unsafePerformIO उपयोग करने के लिए है? मैं एक असुरक्षित आईओआरआईफ़ या एमवीआर में एक बूल लपेट सकता हूं ताकि इन प्रारंभिक कॉलों को बाद की कॉलों को अनदेखा कर दिया जा सके (कॉल, जहां वैश्विक, छुपा आईओआरएफ राज्य गलत है)।

यदि नहीं, तो यह करने के लिए सही तरीके से क्या है?

उत्तर

11

मैं एक बार आरंभ और सबूत है कि आप मशीन प्रारंभ कर दिया है के रूप में एक unforgeable टोकन प्रदान करने के दृष्टिकोण पसंद करते हैं।

तो अपने सबूत होगा:

data Token = Token 

जो आप संक्षेप में निर्यात करें।

फिर अपने आरंभीकरण समारोह इस सबूत लौट सकते हैं।

init :: IO Token 

अब, आप अपने एपीआई के लिए है कि सबूत पारित करने के लिए की जरूरत है:

bar :: Token -> IO Int 
bar !tok = c_call_bar 

आदि

अब आप इस चीज एक इकाई, या करने के लिए कुछ उच्च आदेश प्रारंभ पर्यावरण के साथ लपेट कर सकते हैं इसे क्लीनर बनाएं, लेकिन यह मूल विचार है।

छिपे हुए राज्य का उपयोग कर सी पुस्तकालयों को शुरू करने में समस्या यह है कि आप लाइब्रेरी तक पहुंच को समानांतर करने में सक्षम नहीं हैं, या जीएचसीआई में समस्याएं हैं, संकलित और बाइटकोड मिश्रण करते हैं, सी लाइब्रेरी लोड के दो अलग-अलग संस्करणों के साथ (जो एक लिंकर त्रुटि के साथ असफल हो जाएगा)।

+2

एक वैकल्पिक देखा गया है कि उपयोग मुख्य आसपास 'withX' ​​आवरण है। यह कोई स्थिर गारेंटेस नहीं देता है, मैं बस कह रहा हूं कि प्राथमिकता है (पूर्व में 'नेटवर्क पैकेज से सॉकेट्स डीओ')। –

+1

आह हाँ, अच्छा बिंदु। 'टूटे हुए $ \ t ->' से सरल, लेकिन कोई गारंटी नहीं है। –

+1

आह, उत्कृष्ट! यह एक बेहतर समाधान है। मैं इस बारे में चिंतित था कि ग्लोबल स्टेट मल्टीथ्रेडिंग के साथ कैसे बातचीत करेगा (एक असुरक्षित एमवीआर थ्रेड स्थानीय, रनटाइम स्थानीय है?)। यह प्रारंभिक और छुपा के बजाय हास्केल रनटाइम में प्रारंभिक विफलता को स्थानीयकरण भी बनाता है। –

2

मैं/बजाय withSocketsDoby Neil Mitchell के लिए है कि वर्तमान में कुछ नए चाल is suggested, evaluate के आधार पर ध्यान दें करना चाहते हैं ("बाध्य करता है अपने तर्क कमजोर सिर करने के लिए सामान्य रूप से मूल्यांकन किया जाना करने के लिए जब उसके एवज में आईओ कार्रवाई निष्पादित किया जाता है।"):

withSocketsDo act = do evaluate withSocketsInit; act 

{-# NOINLINE withSocketsInit #-} 
withSocketsInit = unsafePerformIO $ do 
    initWinsock 
    termWinsock 

आवश्यकता को हटाकर कॉल करने के लिए withSocketsDo के लिए किया गया यह बहुत सस्ता बनाने, तो यह हर जगह छिड़क यह आवश्यकता हो सकती है मेरे दृष्टिकोण।

ज़रूरी नहीं कि यह एक सुंदर विचार है ...

(भी his answer पुस्तकालय में इस अद्यतन की घोषणा देखें।)

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