How do I create a storable instance for this structure without c2hs or other tools?

心已入冬 提交于 2019-12-10 16:26:10

问题


This structure:

typedef struct Atom_ {
    float x;
    float y;
    float z;
    int col;
} Atom;

corresponds to this type:

data Atom = Atom { pos :: V3 Float, col :: Int }

How do I create a storable instance for Atom so that I can send an Atoms on Haskell to a C function that expects an Atom?


回答1:


I can't currently guarantee that this will work exactly as shown (I don't have the environment set up on this computer), but it should be a good first step towards getting it right:

import Foreign.Storable
import Foreign.Ptr

instance Storable Atom where
    -- Don't make this static, let the compiler choose depending
    -- on the platform
    sizeOf _ = 3 * sizeOf (0 :: Float) + sizeOf (0 :: Int)
    -- You may need to fiddle with this, and with your corresponding C
    -- code if you have the ability to, alignment can be tricky, but
    -- in this case you can pretty safely assume it'll be the alignment
    -- for `Float`
    alignment _ = alignment (0 :: Float)
    -- These are pretty straightforward, and obviously order matters here
    -- a great deal.  I clearly haven't made this the most optimized it
    -- could be, I'm going for clarity of code instead
    peek ptr = do
        let floatSize = sizeOf (0 :: Float)
        x   <- peek $ ptr `plusPtr` (0 * floatSize)
        y   <- peek $ ptr `plusPtr` (1 * floatSize)
        z   <- peek $ ptr `plusPtr` (2 * floatSize)
        col <- peek $ ptr `plusPtr` (3 * floatSize)
        return $ Atom (V3 x y z) col
    poke ptr (Atom (V3 x y z) col) = do
        let floatSize = sizeOf (0 :: Float)
        poke (ptr `plusPtr` (0 * floatSize)) x
        poke (ptr `plusPtr` (1 * floatSize)) y
        poke (ptr `plusPtr` (2 * floatSize)) z
        poke (ptr `plusPtr` (3 * floatSize)) col

And this should just work! It could be highly dependent on your C compiler and your platform, though, you'll want to do some extensive testing to make sure it's been laid out correctly.



来源:https://stackoverflow.com/questions/30548229/how-do-i-create-a-storable-instance-for-this-structure-without-c2hs-or-other-too

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!