Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 为读取系统调用编写Haskell FFI_Linux_Haskell_System Calls_Ffi - Fatal编程技术网

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))