From 7e09c1d6810c1a8128c237d12aeaae4eb5de5516 Mon Sep 17 00:00:00 2001 From: George Thomas Date: Thu, 19 Feb 2026 11:11:23 +0000 Subject: [PATCH] Add more complex data types --- haskell/exe/Main.hs | 12 ++++++ haskell/generated/GarnetRs/FunPtr.hs | 59 +++++++++++++++++++++++++- haskell/generated/GarnetRs/Safe.hs | 63 +++++++++++++++++++++++++++- haskell/generated/GarnetRs/Unsafe.hs | 63 +++++++++++++++++++++++++++- rust/garnet_rs.h | 30 +++++++++++++ rust/lib.rs | 24 +++++++++++ 6 files changed, 248 insertions(+), 3 deletions(-) diff --git a/haskell/exe/Main.hs b/haskell/exe/Main.hs index de97264..3038091 100644 --- a/haskell/exe/Main.hs +++ b/haskell/exe/Main.hs @@ -1,9 +1,21 @@ module Main (main) where +import Foreign import Foreign.C +import GarnetRs import GarnetRs.Safe +import HsBindgen.Runtime.Marshal import HsBindgen.Runtime.PtrConst main :: IO () main = do 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) diff --git a/haskell/generated/GarnetRs/FunPtr.hs b/haskell/generated/GarnetRs/FunPtr.hs index 8e6972e..432fe38 100644 --- a/haskell/generated/GarnetRs/FunPtr.hs +++ b/haskell/generated/GarnetRs/FunPtr.hs @@ -12,6 +12,7 @@ import qualified HsBindgen.Runtime.Internal.CAPI import qualified HsBindgen.Runtime.Internal.HasFFIType import qualified HsBindgen.Runtime.PtrConst import Data.Void (Void) +import GarnetRs import Prelude (IO) $(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;" , "}" + , "/* 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@ @@ -38,10 +55,50 @@ hs_bindgen_faf62265b53521d3 = {-# NOINLINE hello #-} {-| __C declaration:__ @hello@ - __defined at:__ @garnet_rs.h 6:6@ + __defined at:__ @garnet_rs.h 32:6@ __exported by:__ @garnet_rs.h@ -} hello :: Ptr.FunPtr ((HsBindgen.Runtime.PtrConst.PtrConst FC.CChar) -> IO ()) hello = 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 diff --git a/haskell/generated/GarnetRs/Safe.hs b/haskell/generated/GarnetRs/Safe.hs index efb2b0e..de1581a 100644 --- a/haskell/generated/GarnetRs/Safe.hs +++ b/haskell/generated/GarnetRs/Safe.hs @@ -11,6 +11,7 @@ import qualified HsBindgen.Runtime.Internal.CAPI import qualified HsBindgen.Runtime.Internal.HasFFIType import qualified HsBindgen.Runtime.PtrConst import Data.Void (Void) +import GarnetRs import Prelude (IO) $(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);" , "}" + , "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@ @@ -37,7 +50,7 @@ hs_bindgen_433ea2a26af4e593 = {-| __C declaration:__ @hello@ - __defined at:__ @garnet_rs.h 6:6@ + __defined at:__ @garnet_rs.h 32:6@ __exported by:__ @garnet_rs.h@ -} @@ -46,3 +59,51 @@ hello :: -- ^ __C declaration:__ @c@ -> IO () 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 diff --git a/haskell/generated/GarnetRs/Unsafe.hs b/haskell/generated/GarnetRs/Unsafe.hs index 41ba945..2aec563 100644 --- a/haskell/generated/GarnetRs/Unsafe.hs +++ b/haskell/generated/GarnetRs/Unsafe.hs @@ -11,6 +11,7 @@ import qualified HsBindgen.Runtime.Internal.CAPI import qualified HsBindgen.Runtime.Internal.HasFFIType import qualified HsBindgen.Runtime.PtrConst import Data.Void (Void) +import GarnetRs import Prelude (IO) $(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);" , "}" + , "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@ @@ -37,7 +50,7 @@ hs_bindgen_2dfe97662a4d6377 = {-| __C declaration:__ @hello@ - __defined at:__ @garnet_rs.h 6:6@ + __defined at:__ @garnet_rs.h 32:6@ __exported by:__ @garnet_rs.h@ -} @@ -46,3 +59,51 @@ hello :: -- ^ __C declaration:__ @c@ -> IO () 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 diff --git a/rust/garnet_rs.h b/rust/garnet_rs.h index ae756f1..80da9bd 100644 --- a/rust/garnet_rs.h +++ b/rust/garnet_rs.h @@ -3,4 +3,34 @@ #include #include +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_struct(const struct T *t); + +void hello_shape(const struct Shape *s); diff --git a/rust/lib.rs b/rust/lib.rs index 0d4431b..e84bdbc 100644 --- a/rust/lib.rs +++ b/rust/lib.rs @@ -8,3 +8,27 @@ fn say_hello(name: &str) { extern "C" fn hello(c: *const c_char) -> () { 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)) +}