为读取系统调用写入 Haskell FFI
Writing Haskell FFI for read system call
read
函数定义如下:
#include <unistd.h>
ssize_t read(int fd, void *buf, size_t len)
我想为此编写一个 Haskell FFI。这是我的尝试(无法编译):
foreign import ccall unsafe "read" c_read :: CInt -> Ptr () -> CSize -> IO CSsize
read :: Int -- ^ file descriptor
-> Int64 -- ^ Bytes to allocate
-> Word64 -- ^ Read upto this many bytes
-> IO (String, Int64)
read fd bytes len = do
allocaBytes (fromIntegral bytes) (\ptr -> do
size <- c_read (fromIntegral fd) ptr (fromIntegral len)
dat <- peekByteOff (castPtr ptr) (fromIntegral size) :: IO String
return (dat, (fromIntegral size))
)
它无法编译,因为没有 String
的 Storable 实例。关于如何为此编写 FFI 的任何提示?
Foreign.C.String 是这里的传统解决方案。
根据 Michael Snoyman 和 Reid Barton 的建议,我最终想出了这个解决方案作为开始:
foreign import ccall safe "read" c_read :: CInt -> Ptr () -> CSize -> IO CSsize
read :: Int -- ^ file descriptor
-> Int64 -- ^ Bytes to allocate
-> Word64 -- ^ Read upto this many bytes
-> IO (ByteString, Int64)
read fd bytes len = do
(ptr :: Ptr ()) <- mallocBytes (fromIntegral bytes)
size <- c_read (fromIntegral fd) ptr (fromIntegral len)
bstring <- packCStringLen (castPtr ptr, fromIntegral size)
free ptr
return (bstring, (fromIntegral size))
read
函数定义如下:
#include <unistd.h>
ssize_t read(int fd, void *buf, size_t len)
我想为此编写一个 Haskell FFI。这是我的尝试(无法编译):
foreign import ccall unsafe "read" c_read :: CInt -> Ptr () -> CSize -> IO CSsize
read :: Int -- ^ file descriptor
-> Int64 -- ^ Bytes to allocate
-> Word64 -- ^ Read upto this many bytes
-> IO (String, Int64)
read fd bytes len = do
allocaBytes (fromIntegral bytes) (\ptr -> do
size <- c_read (fromIntegral fd) ptr (fromIntegral len)
dat <- peekByteOff (castPtr ptr) (fromIntegral size) :: IO String
return (dat, (fromIntegral size))
)
它无法编译,因为没有 String
的 Storable 实例。关于如何为此编写 FFI 的任何提示?
Foreign.C.String 是这里的传统解决方案。
根据 Michael Snoyman 和 Reid Barton 的建议,我最终想出了这个解决方案作为开始:
foreign import ccall safe "read" c_read :: CInt -> Ptr () -> CSize -> IO CSsize
read :: Int -- ^ file descriptor
-> Int64 -- ^ Bytes to allocate
-> Word64 -- ^ Read upto this many bytes
-> IO (ByteString, Int64)
read fd bytes len = do
(ptr :: Ptr ()) <- mallocBytes (fromIntegral bytes)
size <- c_read (fromIntegral fd) ptr (fromIntegral len)
bstring <- packCStringLen (castPtr ptr, fromIntegral size)
free ptr
return (bstring, (fromIntegral size))