可存储的空数据声明 [英] Storable empty data declaration

查看:101
本文介绍了可存储的空数据声明的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图为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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆