Je tente de créer un wrapper Haskell pour une bibliothèque C. Les structures sous-jacentes sont trop compliquées pour être exprimées en tant que types explicites, et je ne les utilise pas autrement que pour passer d'une fonction C à l'autre, j'utilise donc EmptyDataDecls
pour que GHC puisse les résoudre. Ce dont j'ai besoin est un pointeur vers un de ces types de données, mais quand je tente d'en créer un avec alloca
il se plaint que les données ne sont pas du type Storable
. Par exemple:Déclaration de données vides pouvant être stockées
{-# 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 ne compile pas, en disant il n'y a pas d'exemple pour Storable Struct
. Je pourrais mettre en œuvre moi-même:
instance Storable Struct where
sizeOf _ = ...
alignment _ = ...
Mais qui se rapproche de l'encontre du but - Je ne veux pas avoir à définir de telles choses si je ne me soucie pas ce qui est dans le struct. J'ai remarqué qu'un pointeur sur un pointeur fonctionne bien, car la classe Ptr
est Storable
. Je peux donc accomplir ce que je vise en utilisant peek
sur ptr
avant d'appeler get_struct
:
main = alloca $ \ptr -> do
ptr <- peek ptr
get_struct ptr
Cela se sent comme un hack, cependant.
Existe-t-il un moyen de prendre en compte les déclarations de données vides Storable
sans définir d'instance?
Ceci est un hack. Vous n'allouez jamais d'espace pour le pointeur interne; vous pointez simplement sur une mémoire aléatoire. De cette façon, se trouve le segfaults. –
Donc, si je veux légitimement un pointeur sur un pointeur, je devrais utiliser deux appels 'alloca' et ensuite' poke' un pointeur dans l'autre, non? – zmthy
oui (ou utilisez une autre forme d'allocation). Les utilisations les plus courantes pour un pointeur sur un pointeur sont des valeurs de pointeur, auquel cas la fonction liée fait l'allocation, et des tableaux de chaînes (pensez 'argv'). Th –