Linux 为读取系统调用编写Haskell FFI
Linux 为读取系统调用编写Haskell FFI,linux,haskell,system-calls,ffi,Linux,Haskell,System Calls,Ffi,read函数的定义如下: #include <unistd.h> ssize_t read(int fd, void *buf, size_t len) #包括 ssize_t read(整型fd,无效*buf,尺寸长度) 我想为此写一份Haskell FFI。这是我的尝试(未编译): foreign import ccall不安全的“read”c_read::CInt->Ptr()->CSize->IO CSsize 读取::Int--^文件描述符 ->Int64--^要分配
read
函数的定义如下:
#include <unistd.h>
ssize_t read(int fd, void *buf, size_t len)
#包括
ssize_t read(整型fd,无效*buf,尺寸长度)
我想为此写一份Haskell FFI。这是我的尝试(未编译):
foreign import ccall不安全的“read”c_read::CInt->Ptr()->CSize->IO CSsize
读取::Int--^文件描述符
->Int64--^要分配的字节数
->Word64--^最多读取这么多字节
->IO(字符串,Int64)
读取fd字节len=do
allocaBytes(来自整数字节)(\ptr->do
尺寸是这里的传统解决方案。根据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))
foreign import ccall safe“read”c_read::CInt->Ptr()->CSize->IO CSsize
读取::Int--^文件描述符
->Int64--^要分配的字节数
->Word64--^最多读取这么多字节
->IO(ByteString,Int64)
读取fd字节len=do
(ptr::ptr())我建议返回一个ByteString
而不是字符串,因为后者将意味着一种可能不正确的字符编码。为了创建ByteString
,您可能需要malloc
缓冲区,而不是使用allocaBytes
,然后将该指针重新用于ByteStrin你的PEEK线过于简单化,实际上是错误的,因为你使用的是<代码>大小>代码>作为开始阅读的索引。同时,这个API看起来非常危险。至少你应该检查<代码>字节> = LeN<代码>,所以用户不能说<代码>读fd 0 5000 < /COD>,对吗?编辑:实际上这更棘手。是的。fromIntegral bytes::some type>=fromIntegralLen::that type
类型匹配您的强制转换/c绑定。@ThomasM.DuBuisson是的,我知道。我想让它工作,然后担心正确性。@MichaelSnoyman这是一个合理的开始:?我正在使用CString
作为中间类型。
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))