Add more complex data types

This commit is contained in:
George Thomas 2026-02-19 11:11:23 +00:00
parent 0a1911862f
commit 7e09c1d681
6 changed files with 248 additions and 3 deletions

View File

@ -1,9 +1,21 @@
module Main (main) where module Main (main) where
import Foreign
import Foreign.C import Foreign.C
import GarnetRs
import GarnetRs.Safe import GarnetRs.Safe
import HsBindgen.Runtime.Marshal
import HsBindgen.Runtime.PtrConst import HsBindgen.Runtime.PtrConst
main :: IO () main :: IO ()
main = do main = do
withCString "Haskell" $ hello . unsafeFromPtr withCString "Haskell" $ hello . unsafeFromPtr
alloca \ptr -> do
writeRaw ptr T{a = CBool 1, b = 42}
hello_struct (unsafeFromPtr ptr)
alloca \ptr -> do
writeRaw ptr (Shape (Shape_Tag 0) (set_shape_body_circle (Circle_Body 3.14)))
hello_shape (unsafeFromPtr ptr)
alloca \ptr -> do
writeRaw ptr (Shape (Shape_Tag 1) (set_shape_body_rectangle (Rectangle_Body 10.0 5.0)))
hello_shape (unsafeFromPtr ptr)

View File

@ -12,6 +12,7 @@ import qualified HsBindgen.Runtime.Internal.CAPI
import qualified HsBindgen.Runtime.Internal.HasFFIType import qualified HsBindgen.Runtime.Internal.HasFFIType
import qualified HsBindgen.Runtime.PtrConst import qualified HsBindgen.Runtime.PtrConst
import Data.Void (Void) import Data.Void (Void)
import GarnetRs
import Prelude (IO) import Prelude (IO)
$(HsBindgen.Runtime.Internal.CAPI.addCSource (HsBindgen.Runtime.Internal.CAPI.unlines $(HsBindgen.Runtime.Internal.CAPI.addCSource (HsBindgen.Runtime.Internal.CAPI.unlines
@ -24,6 +25,22 @@ $(HsBindgen.Runtime.Internal.CAPI.addCSource (HsBindgen.Runtime.Internal.CAPI.un
, "{" , "{"
, " return &hello;" , " return &hello;"
, "}" , "}"
, "/* com_garnet_GarnetRs_get_hello_struct */"
, "__attribute__ ((const))"
, "void (*hs_bindgen_0f8c37ef19b17a6d (void)) ("
, " struct T const *arg1"
, ")"
, "{"
, " return &hello_struct;"
, "}"
, "/* com_garnet_GarnetRs_get_hello_shape */"
, "__attribute__ ((const))"
, "void (*hs_bindgen_287ff3ac660f333b (void)) ("
, " struct Shape const *arg1"
, ")"
, "{"
, " return &hello_shape;"
, "}"
])) ]))
-- __unique:__ @com_garnet_GarnetRs_get_hello@ -- __unique:__ @com_garnet_GarnetRs_get_hello@
@ -38,10 +55,50 @@ hs_bindgen_faf62265b53521d3 =
{-# NOINLINE hello #-} {-# NOINLINE hello #-}
{-| __C declaration:__ @hello@ {-| __C declaration:__ @hello@
__defined at:__ @garnet_rs.h 6:6@ __defined at:__ @garnet_rs.h 32:6@
__exported by:__ @garnet_rs.h@ __exported by:__ @garnet_rs.h@
-} -}
hello :: Ptr.FunPtr ((HsBindgen.Runtime.PtrConst.PtrConst FC.CChar) -> IO ()) hello :: Ptr.FunPtr ((HsBindgen.Runtime.PtrConst.PtrConst FC.CChar) -> IO ())
hello = hello =
GHC.IO.Unsafe.unsafePerformIO hs_bindgen_faf62265b53521d3 GHC.IO.Unsafe.unsafePerformIO hs_bindgen_faf62265b53521d3
-- __unique:__ @com_garnet_GarnetRs_get_hello_struct@
foreign import ccall unsafe "hs_bindgen_0f8c37ef19b17a6d" hs_bindgen_0f8c37ef19b17a6d_base ::
IO (Ptr.FunPtr Void)
-- __unique:__ @com_garnet_GarnetRs_get_hello_struct@
hs_bindgen_0f8c37ef19b17a6d :: IO (Ptr.FunPtr ((HsBindgen.Runtime.PtrConst.PtrConst T) -> IO ()))
hs_bindgen_0f8c37ef19b17a6d =
HsBindgen.Runtime.Internal.HasFFIType.fromFFIType hs_bindgen_0f8c37ef19b17a6d_base
{-# NOINLINE hello_struct #-}
{-| __C declaration:__ @hello_struct@
__defined at:__ @garnet_rs.h 34:6@
__exported by:__ @garnet_rs.h@
-}
hello_struct :: Ptr.FunPtr ((HsBindgen.Runtime.PtrConst.PtrConst T) -> IO ())
hello_struct =
GHC.IO.Unsafe.unsafePerformIO hs_bindgen_0f8c37ef19b17a6d
-- __unique:__ @com_garnet_GarnetRs_get_hello_shape@
foreign import ccall unsafe "hs_bindgen_287ff3ac660f333b" hs_bindgen_287ff3ac660f333b_base ::
IO (Ptr.FunPtr Void)
-- __unique:__ @com_garnet_GarnetRs_get_hello_shape@
hs_bindgen_287ff3ac660f333b :: IO (Ptr.FunPtr ((HsBindgen.Runtime.PtrConst.PtrConst Shape) -> IO ()))
hs_bindgen_287ff3ac660f333b =
HsBindgen.Runtime.Internal.HasFFIType.fromFFIType hs_bindgen_287ff3ac660f333b_base
{-# NOINLINE hello_shape #-}
{-| __C declaration:__ @hello_shape@
__defined at:__ @garnet_rs.h 36:6@
__exported by:__ @garnet_rs.h@
-}
hello_shape :: Ptr.FunPtr ((HsBindgen.Runtime.PtrConst.PtrConst Shape) -> IO ())
hello_shape =
GHC.IO.Unsafe.unsafePerformIO hs_bindgen_287ff3ac660f333b

View File

@ -11,6 +11,7 @@ import qualified HsBindgen.Runtime.Internal.CAPI
import qualified HsBindgen.Runtime.Internal.HasFFIType import qualified HsBindgen.Runtime.Internal.HasFFIType
import qualified HsBindgen.Runtime.PtrConst import qualified HsBindgen.Runtime.PtrConst
import Data.Void (Void) import Data.Void (Void)
import GarnetRs
import Prelude (IO) import Prelude (IO)
$(HsBindgen.Runtime.Internal.CAPI.addCSource (HsBindgen.Runtime.Internal.CAPI.unlines $(HsBindgen.Runtime.Internal.CAPI.addCSource (HsBindgen.Runtime.Internal.CAPI.unlines
@ -21,6 +22,18 @@ $(HsBindgen.Runtime.Internal.CAPI.addCSource (HsBindgen.Runtime.Internal.CAPI.un
, "{" , "{"
, " hello(arg1);" , " hello(arg1);"
, "}" , "}"
, "void hs_bindgen_51157946af5519c9 ("
, " struct T const *arg1"
, ")"
, "{"
, " hello_struct(arg1);"
, "}"
, "void hs_bindgen_7de06f1fd827ca60 ("
, " struct Shape const *arg1"
, ")"
, "{"
, " hello_shape(arg1);"
, "}"
])) ]))
-- __unique:__ @com_garnet_GarnetRs_Safe_hello@ -- __unique:__ @com_garnet_GarnetRs_Safe_hello@
@ -37,7 +50,7 @@ hs_bindgen_433ea2a26af4e593 =
{-| __C declaration:__ @hello@ {-| __C declaration:__ @hello@
__defined at:__ @garnet_rs.h 6:6@ __defined at:__ @garnet_rs.h 32:6@
__exported by:__ @garnet_rs.h@ __exported by:__ @garnet_rs.h@
-} -}
@ -46,3 +59,51 @@ hello ::
-- ^ __C declaration:__ @c@ -- ^ __C declaration:__ @c@
-> IO () -> IO ()
hello = hs_bindgen_433ea2a26af4e593 hello = hs_bindgen_433ea2a26af4e593
-- __unique:__ @com_garnet_GarnetRs_Safe_hello_struct@
foreign import ccall safe "hs_bindgen_51157946af5519c9" hs_bindgen_51157946af5519c9_base ::
Ptr.Ptr Void
-> IO ()
-- __unique:__ @com_garnet_GarnetRs_Safe_hello_struct@
hs_bindgen_51157946af5519c9 ::
HsBindgen.Runtime.PtrConst.PtrConst T
-> IO ()
hs_bindgen_51157946af5519c9 =
HsBindgen.Runtime.Internal.HasFFIType.fromFFIType hs_bindgen_51157946af5519c9_base
{-| __C declaration:__ @hello_struct@
__defined at:__ @garnet_rs.h 34:6@
__exported by:__ @garnet_rs.h@
-}
hello_struct ::
HsBindgen.Runtime.PtrConst.PtrConst T
-- ^ __C declaration:__ @t@
-> IO ()
hello_struct = hs_bindgen_51157946af5519c9
-- __unique:__ @com_garnet_GarnetRs_Safe_hello_shape@
foreign import ccall safe "hs_bindgen_7de06f1fd827ca60" hs_bindgen_7de06f1fd827ca60_base ::
Ptr.Ptr Void
-> IO ()
-- __unique:__ @com_garnet_GarnetRs_Safe_hello_shape@
hs_bindgen_7de06f1fd827ca60 ::
HsBindgen.Runtime.PtrConst.PtrConst Shape
-> IO ()
hs_bindgen_7de06f1fd827ca60 =
HsBindgen.Runtime.Internal.HasFFIType.fromFFIType hs_bindgen_7de06f1fd827ca60_base
{-| __C declaration:__ @hello_shape@
__defined at:__ @garnet_rs.h 36:6@
__exported by:__ @garnet_rs.h@
-}
hello_shape ::
HsBindgen.Runtime.PtrConst.PtrConst Shape
-- ^ __C declaration:__ @s@
-> IO ()
hello_shape = hs_bindgen_7de06f1fd827ca60

View File

@ -11,6 +11,7 @@ import qualified HsBindgen.Runtime.Internal.CAPI
import qualified HsBindgen.Runtime.Internal.HasFFIType import qualified HsBindgen.Runtime.Internal.HasFFIType
import qualified HsBindgen.Runtime.PtrConst import qualified HsBindgen.Runtime.PtrConst
import Data.Void (Void) import Data.Void (Void)
import GarnetRs
import Prelude (IO) import Prelude (IO)
$(HsBindgen.Runtime.Internal.CAPI.addCSource (HsBindgen.Runtime.Internal.CAPI.unlines $(HsBindgen.Runtime.Internal.CAPI.addCSource (HsBindgen.Runtime.Internal.CAPI.unlines
@ -21,6 +22,18 @@ $(HsBindgen.Runtime.Internal.CAPI.addCSource (HsBindgen.Runtime.Internal.CAPI.un
, "{" , "{"
, " hello(arg1);" , " hello(arg1);"
, "}" , "}"
, "void hs_bindgen_29d823ada2bc7302 ("
, " struct T const *arg1"
, ")"
, "{"
, " hello_struct(arg1);"
, "}"
, "void hs_bindgen_b3f40a03f07eaa85 ("
, " struct Shape const *arg1"
, ")"
, "{"
, " hello_shape(arg1);"
, "}"
])) ]))
-- __unique:__ @com_garnet_GarnetRs_Unsafe_hello@ -- __unique:__ @com_garnet_GarnetRs_Unsafe_hello@
@ -37,7 +50,7 @@ hs_bindgen_2dfe97662a4d6377 =
{-| __C declaration:__ @hello@ {-| __C declaration:__ @hello@
__defined at:__ @garnet_rs.h 6:6@ __defined at:__ @garnet_rs.h 32:6@
__exported by:__ @garnet_rs.h@ __exported by:__ @garnet_rs.h@
-} -}
@ -46,3 +59,51 @@ hello ::
-- ^ __C declaration:__ @c@ -- ^ __C declaration:__ @c@
-> IO () -> IO ()
hello = hs_bindgen_2dfe97662a4d6377 hello = hs_bindgen_2dfe97662a4d6377
-- __unique:__ @com_garnet_GarnetRs_Unsafe_hello_struct@
foreign import ccall unsafe "hs_bindgen_29d823ada2bc7302" hs_bindgen_29d823ada2bc7302_base ::
Ptr.Ptr Void
-> IO ()
-- __unique:__ @com_garnet_GarnetRs_Unsafe_hello_struct@
hs_bindgen_29d823ada2bc7302 ::
HsBindgen.Runtime.PtrConst.PtrConst T
-> IO ()
hs_bindgen_29d823ada2bc7302 =
HsBindgen.Runtime.Internal.HasFFIType.fromFFIType hs_bindgen_29d823ada2bc7302_base
{-| __C declaration:__ @hello_struct@
__defined at:__ @garnet_rs.h 34:6@
__exported by:__ @garnet_rs.h@
-}
hello_struct ::
HsBindgen.Runtime.PtrConst.PtrConst T
-- ^ __C declaration:__ @t@
-> IO ()
hello_struct = hs_bindgen_29d823ada2bc7302
-- __unique:__ @com_garnet_GarnetRs_Unsafe_hello_shape@
foreign import ccall unsafe "hs_bindgen_b3f40a03f07eaa85" hs_bindgen_b3f40a03f07eaa85_base ::
Ptr.Ptr Void
-> IO ()
-- __unique:__ @com_garnet_GarnetRs_Unsafe_hello_shape@
hs_bindgen_b3f40a03f07eaa85 ::
HsBindgen.Runtime.PtrConst.PtrConst Shape
-> IO ()
hs_bindgen_b3f40a03f07eaa85 =
HsBindgen.Runtime.Internal.HasFFIType.fromFFIType hs_bindgen_b3f40a03f07eaa85_base
{-| __C declaration:__ @hello_shape@
__defined at:__ @garnet_rs.h 36:6@
__exported by:__ @garnet_rs.h@
-}
hello_shape ::
HsBindgen.Runtime.PtrConst.PtrConst Shape
-- ^ __C declaration:__ @s@
-> IO ()
hello_shape = hs_bindgen_b3f40a03f07eaa85

View File

@ -3,4 +3,34 @@
#include <stdint.h> #include <stdint.h>
#include <stdlib.h> #include <stdlib.h>
typedef struct T {
bool a;
uint8_t b;
} T;
typedef uint8_t Shape_Tag;
#define Circle 0
#define Rectangle 1
typedef struct Circle_Body {
double radius;
} Circle_Body;
typedef struct Rectangle_Body {
double width;
double height;
} Rectangle_Body;
typedef struct Shape {
Shape_Tag tag;
union {
Circle_Body circle;
Rectangle_Body rectangle;
} body;
} Shape;
void hello(const char *c); void hello(const char *c);
void hello_struct(const struct T *t);
void hello_shape(const struct Shape *s);

View File

@ -8,3 +8,27 @@ fn say_hello(name: &str) {
extern "C" fn hello(c: *const c_char) -> () { extern "C" fn hello(c: *const c_char) -> () {
say_hello(unsafe { CStr::from_ptr(c) }.to_str().unwrap()) say_hello(unsafe { CStr::from_ptr(c) }.to_str().unwrap())
} }
#[repr(C)]
#[derive(Debug)]
struct T {
a: bool,
b: u8,
}
#[unsafe(no_mangle)]
extern "C" fn hello_struct(t: &T) -> () {
say_hello(&format!("{:?}", t))
}
#[repr(C, u8)]
#[allow(dead_code)]
#[derive(Debug)]
enum Shape {
Circle { radius: f64 },
Rectangle { width: f64, height: f64 },
}
#[unsafe(no_mangle)]
extern "C" fn hello_shape(s: &Shape) -> () {
say_hello(&format!("{:?}", s))
}