2010-03-05 21 views
9

मैं बहुत कम स्तर पर डेटा में हेरफेर करना चाहता हूं।हास्केल में पॉइंटर मूल्य कैसे प्राप्त करें?

इसलिए मेरे पास एक ऐसा फ़ंक्शन है जो वर्चुअल मेमोरी एड्रेस को पूर्णांक के रूप में प्राप्त करता है और इस मेमोरी पते के साथ "सामान करता है"। मैंने इस फ़ंक्शन को सी से इंटरफेस किया है, इसलिए इसमें (CUInt -> a) टाइप है। मैं जिस मेमोरी को लिंक करना चाहता हूं वह एक फ़ाइल में Word8 है। अफसोस की बात है, मुझे नहीं पता कि पॉइंटर मान को उस Word8 पर कैसे पहुंचाया जाए।

स्पष्ट होने के लिए, मुझे Word8 के मान की आवश्यकता नहीं है, मुझे वर्चुअल मेमोरी एड्रेस के मान की आवश्यकता है, जो कि पॉइंटर का मान है।

+0

आप संकेतक भिन्नता के लिए सी में एक समारोह नहीं जा सकते? – kennytm

उत्तर

6

एक साधारण उदाहरण के लिए, कहें कि आप पॉइंटर को ऑफ़सेट जोड़ना चाहते हैं।

मोर्चा बात:

module Main where 
import Control.Monad (forM_) 
import Data.Char (chr) 
import Data.Word (Word8) 
import Foreign.ForeignPtr (ForeignPtr, withForeignPtr) 
import Foreign.Ptr (Ptr, plusPtr) 
import Foreign.Storable (peek) 
import System.IO.MMap (Mode(ReadOnly), mmapFileForeignPtr) 

हाँ, आप ने लिखा है कि आप Word8 का मूल्य नहीं करना चाहते, लेकिन मैं प्रदर्शन करने के लिए है कि सूचक मान्य है peek के साथ लिया गया है। आप returnPtrwithForeignPtr अंदर से करने के लिए परीक्षा हो सकती है, लेकिन प्रलेखन कि के खिलाफ चेतावनी देते हैं:

ध्यान दें कि यह सुरक्षित कार्रवाई से सूचक लौट सकते हैं और इसका इस्तेमाल करने के बाद कार्य पूरा करता है करने के लिए नहीं है। सूचक का सभी उपयोग withForeignPtr ब्रैकेट के अंदर होना चाहिए। इस असुरक्षा का कारण नीचे unsafeForeignPtrToPtr जैसा है: अंतिमकर्ता अपेक्षा से पहले चला सकता है, क्योंकि संकलक केवल ForeignPtr ऑब्जेक्ट का उपयोग ट्रैक कर सकता है, न कि Ptr ऑब्जेक्ट से बना है।

कोड सीधा है:

doStuff :: ForeignPtr Word8 -> Int -> IO() 
doStuff fp i = 
    withForeignPtr fp $ \p -> do 
    let addr = p `plusPtr` i 
    val <- peek addr :: IO Word8 
    print (addr, val, chr $ fromIntegral val) 

अनुमान लगाने के लिए अपने प्रश्न से "एक फ़ाइल में एक Word8", मुख्य प्रोग्राम एक फ़ाइल स्मृति-नक्शे और बफर स्मृति पते के साथ काम करना है कि उपयोग करता है।

main :: IO() 
main = do 
    (p,offset,size) <- mmapFileForeignPtr path mode range 
    forM_ [0 .. size-1] $ \i -> do 
    doStuff p (offset + i) 
    where 
    path = "/tmp/input.dat" 
    mode = ReadOnly 
    range = Nothing 
-- range = Just (4,3) 

आउटपुट:

(0x00007f1b40edd000,71,'G') 
(0x00007f1b40edd001,117,'u') 
(0x00007f1b40edd002,116,'t') 
(0x00007f1b40edd003,101,'e') 
(0x00007f1b40edd004,110,'n') 
(0x00007f1b40edd005,32,' ') 
(0x00007f1b40edd006,77,'M') 
(0x00007f1b40edd007,111,'o') 
(0x00007f1b40edd008,114,'r') 
(0x00007f1b40edd009,103,'g') 
(0x00007f1b40edd00a,101,'e') 
(0x00007f1b40edd00b,110,'n') 
(0x00007f1b40edd00c,33,'!') 
(0x00007f1b40edd00d,10,'\n')
3

आप शायद इसे ptrToIntPtr और शायद fromIntegral पर एक CUInt बनाने के लिए देख रहे हैं।

ध्यान दें कि एक सीयूआईएनटी सभी प्लेटफार्मों पर एक सूचक का प्रतिनिधित्व नहीं कर सकता है।

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