可存储的空数据声明 [英] Storable empty data declaration
问题描述
我试图为C库创建一个Haskell包装器。底层的结构太复杂了,不能用表达式来显示,除了在C函数之间传递外,我实际上并没有使用它们,所以我使用 EmptyDataDecls
来让GHC
我需要的是指向这些数据类型之一的指针,但是当我尝试使用 alloca
它抱怨数据不是 Storable
类型。例如:
{ - #LANGUAGE ForeignFunctionInterface,EmptyDataDecls# - }
模块Main其中
导入Foreign.Marshal.Alloc
导入Foreign.Ptr
数据结构
外部导入ccallheader.h get_struct
get_struct :: Ptr Struct - > IO()
main = alloca $ \ptr - > get_struct ptr
GHC不会编译这个,表示没有 Storable的实例结构
。我可以自己实现:
instance Stable Struct其中
sizeOf _ = ...
alignment _ = ...
但是这样做已经接近了击败目的 - 我不想定义这样的事情,如果我不在乎结构中有什么。
我注意到指向指针的指针工作正常,因为 Ptr
类是可存储
。所以我可以在调用 get_struct之前,通过在
: ptr
上使用 peek
来实现我的目标。
main = alloca $ \ptr - >做
ptr< - peek ptr
get_struct ptr
这感觉就像一个hack,但是。
有没有办法将空数据声明视为 Storable
,而不定义实例?
如果你不知道它有多大,你就不能分配一些东西。函数是否会忽略它的参数?然后传入一个空指针。否则,您需要为结构实际分配足够的空间 - 不要通过分配零字节或指针大小的缓冲区来削减角点,因为被调用的函数将写入缓冲区末尾,从而破坏内存。
要么完成数据声明,要么编写一个具有适当大小和对齐值的Storable实例;没有办法以某种形式提供大小/对齐数据。
I'm attempting to create a Haskell wrapper for a C library. The underlying structs are too complicated to express as explicit types, and I don't actually use them other than for passing between C functions, so I'm using EmptyDataDecls
to let GHC work it out for me.
What I need is a pointer to one of these data types, but when I attempt to create one with alloca
it complains that the data is not of the type Storable
. For example:
{-# LANGUAGE ForeignFunctionInterface, EmptyDataDecls #-}
module Main where
import Foreign.Marshal.Alloc
import Foreign.Ptr
data Struct
foreign import ccall "header.h get_struct"
get_struct :: Ptr Struct -> IO ()
main = alloca $ \ptr -> get_struct ptr
GHC won't compile this, saying there's no instance for Storable Struct
. I could implement it myself:
instance Storable Struct where
sizeOf _ = ...
alignment _ = ...
But that comes close to defeating the purpose - I don't want to have to define such things if I don't care what's in the struct.
I've noticed that a pointer to a pointer works fine, because the Ptr
class is Storable
. So I can accomplish what I'm aiming for by using peek
on ptr
before calling get_struct
:
main = alloca $ \ptr -> do
ptr <- peek ptr
get_struct ptr
This feels like a hack, though.
Is there a way to get empty data declarations to be considered Storable
without defining an instance?
You can't allocate something if you don't know how big it is. Is the function just going to ignore its argument? Then pass in a null pointer. Otherwise, you need to actually allocate enough space for the struct - don't cut corners by allocating a zero-byte or pointer-sized buffer, as then the called function will write past the end of your buffer, corrupting memory.
Either finish the data declaration, or write a Storable instance with proper size and alignment values; there's no way around providing size/alignment data in some form.
这篇关于可存储的空数据声明的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!