Compare commits

...

5 Commits

Author SHA1 Message Date
George Thomas
2a80e5b219 Minor simplification 2026-02-19 17:22:15 +00:00
George Thomas
e977181252 Avoid typedefs
This makes the header simpler, and silences `hs-bindgen` notices about "squashed" typedefs.
2026-02-19 17:22:15 +00:00
George Thomas
9ca4f615d8 Use simpler tagged union translation
Avoids the worst part of the header hack, and makes Haskell wrapper simpler.
2026-02-19 17:22:15 +00:00
George Thomas
5019af701f Mark pure function 2026-02-19 17:22:15 +00:00
George Thomas
5907a064a7 Use fixed-width integers
Even though `Int` and `isize` should be the same in practice, we can't cleanly convert, as the type information isn't quite there. And anyway, strictly speaking per the report, `Int` is only guaranteed to hold 30 bits.

Note that this is essentially unchanged even if we specify `usize_is_size_t = true` for `cbindgen`.
2026-02-19 17:19:28 +00:00
9 changed files with 175 additions and 164 deletions

View File

@ -16,22 +16,21 @@ import Foreign.C
import GarnetRs qualified as Raw
import GarnetRs.Safe qualified as Raw
import HsBindgen.Runtime.PtrConst
import Unsafe.Coerce
data T = T
{ a :: Bool
, b :: Word8
}
convertT :: T -> Raw.T
convertT T{a, b} = Raw.T{a = CBool $ fromBool a, b}
convertT T{a, b} = Raw.T{a = fromBool a, b}
data Shape
= Circle CDouble
| Rectangle CDouble CDouble
convertShape :: Shape -> Raw.Shape
convertShape = \case
Circle r -> Raw.Shape (Raw.Shape_Tag 0) $ Raw.set_shape_body_circle $ Raw.Circle_Body r
Rectangle w h -> Raw.Shape (Raw.Shape_Tag 1) $ Raw.set_shape_body_rectangle $ Raw.Rectangle_Body w h
Circle r -> Raw.Shape Raw.Circle $ Raw.set_shape_body_circle $ Raw.Circle_Body r
Rectangle w h -> Raw.Shape Raw.Rectangle $ Raw.set_shape_body_rectangle $ Raw.Rectangle_Body w h
hello :: ByteString -> IO ()
hello s = useAsCString s $ Raw.hello . unsafeFromPtr
@ -42,9 +41,5 @@ helloStruct = Raw.hello_struct . convertT
helloShape :: Shape -> IO ()
helloShape = Raw.hello_shape . convertShape
add :: Int -> Int -> IO Int
add a b = from <$> Raw.add (to a) (to b)
where
-- these types should be the same in practice - both are pointer-sized
to = unsafeCoerce @Int @CIntPtr
from = unsafeCoerce @CIntPtr @Int
add :: Int64 -> Int64 -> Int64
add = Raw.add

View File

@ -9,4 +9,4 @@ main = do
helloStruct T{a = False, b = maxBound}
helloShape $ Circle 3.14
helloShape $ Rectangle 10.0 5.0
putStrLn . ("3 + 4 = " <>) . show =<< add 3 4
putStrLn $ "3 + 4 = " <> show (add 3 4)

View File

@ -30,62 +30,18 @@ cbindgen \
--lang c \
--crate garnet-rs \
--output "$HEADER" \
--style tag \
"$RUST_DIR"
echo " Raw header written to $HEADER"
# --- Step 3: Patch the header for hs-bindgen compatibility ---
#
# Two patches are needed, both due to hs-bindgen limitations with cbindgen's
# output for #[repr(C, u8)] tagged enums:
#
# 1. cbindgen emits: enum Shape_Tag { Circle, Rectangle, };
# typedef uint8_t Shape_Tag;
# hs-bindgen needs: typedef uint8_t Shape_Tag;
# #define Circle 0
# #define Rectangle 1
# See: no upstream issue yet for hs-bindgen
#
# 2. cbindgen emits: union { ... }; (anonymous)
# cbindgen emits: union { ... }; (anonymous)
# hs-bindgen needs: union { ... } body; (named)
# See: https://github.com/well-typed/hs-bindgen/issues/1649
echo "=== Patching header ==="
awk '
# State machine for enum->typedef+define transformation
/^enum [A-Za-z_][A-Za-z0-9_]* \{$/ {
in_enum = 1
enum_name = $2
variant_count = 0
delete variants
next
}
in_enum && /^\};$/ {
# Next line should be: typedef <type> <enum_name>;
in_enum = 0
pending_enum = 1
next
}
in_enum {
# Collect variant names (strip trailing comma and whitespace)
v = $0
gsub(/^[[:space:]]+/, "", v)
gsub(/,[[:space:]]*$/, "", v)
if (v != "") {
variants[variant_count] = v
variant_count++
}
next
}
pending_enum && /^typedef [A-Za-z0-9_]+ / {
# Emit: typedef <type> <name>; then #define for each variant
print $0
for (i = 0; i < variant_count; i++) {
printf "#define %s %d\n", variants[i], i
}
pending_enum = 0
next
}
# Name anonymous unions: }; at end of union block inside struct -> } body;
/^ \};$/ && saw_union {
print " } body;"

View File

@ -3,12 +3,12 @@
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE DerivingVia #-}
{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE ExplicitForAll #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
@ -19,8 +19,7 @@
module GarnetRs where
import qualified Data.Array.Byte
import qualified Data.Bits as Bits
import qualified Data.Ix as Ix
import qualified Data.List.NonEmpty
import qualified Data.Primitive.Types
import qualified Data.Proxy
import qualified Foreign as F
@ -28,20 +27,20 @@ import qualified Foreign.C as FC
import qualified GHC.Generics
import qualified GHC.Ptr as Ptr
import qualified GHC.Records
import qualified HsBindgen.Runtime.CEnum
import qualified HsBindgen.Runtime.HasCField
import qualified HsBindgen.Runtime.Internal.Bitfield
import qualified HsBindgen.Runtime.Internal.ByteArray
import qualified HsBindgen.Runtime.Internal.HasFFIType
import qualified HsBindgen.Runtime.Internal.SizedByteArray
import qualified HsBindgen.Runtime.LibC
import qualified HsBindgen.Runtime.Marshal
import Data.Bits (FiniteBits)
import qualified Text.Read
import HsBindgen.Runtime.Internal.TypeEquality (TyEq)
import Prelude ((<*>), (>>), Bounded, Enum, Eq, Int, Integral, Num, Ord, Read, Real, Show, pure)
import Prelude ((<*>), (>>), Eq, Int, Ord, Read, Show, pure, showsPrec)
{-| __C declaration:__ @struct T@
__defined at:__ @garnet_rs.h 6:16@
__defined at:__ @garnet_rs.h 6:8@
__exported by:__ @garnet_rs.h@
-}
@ -114,34 +113,86 @@ instance ( TyEq ty ((HsBindgen.Runtime.HasCField.CFieldType T) "b")
getField =
HsBindgen.Runtime.HasCField.fromPtr (Data.Proxy.Proxy @"b")
{-| __C declaration:__ @Shape_Tag@
{-| __C declaration:__ @enum Shape_Tag@
__defined at:__ @garnet_rs.h 11:17@
__defined at:__ @garnet_rs.h 11:6@
__exported by:__ @garnet_rs.h@
-}
newtype Shape_Tag = Shape_Tag
{ unwrap :: HsBindgen.Runtime.LibC.Word8
{ unwrap :: FC.CUInt
}
deriving stock (GHC.Generics.Generic)
deriving stock (Eq, Ord, Read, Show)
deriving newtype
( HsBindgen.Runtime.Marshal.StaticSize
, HsBindgen.Runtime.Marshal.ReadRaw
, HsBindgen.Runtime.Marshal.WriteRaw
, F.Storable
, HsBindgen.Runtime.Internal.HasFFIType.HasFFIType
, Data.Primitive.Types.Prim
, HsBindgen.Runtime.Internal.Bitfield.Bitfield
, Bits.Bits
, Bounded
, Enum
, FiniteBits
, Integral
, Ix.Ix
, Num
, Real
)
deriving stock (Eq, Ord)
deriving newtype (HsBindgen.Runtime.Internal.HasFFIType.HasFFIType)
instance HsBindgen.Runtime.Marshal.StaticSize Shape_Tag where
staticSizeOf = \_ -> (4 :: Int)
staticAlignment = \_ -> (4 :: Int)
instance HsBindgen.Runtime.Marshal.ReadRaw Shape_Tag where
readRaw =
\ptr0 ->
pure Shape_Tag
<*> HsBindgen.Runtime.Marshal.readRawByteOff ptr0 (0 :: Int)
instance HsBindgen.Runtime.Marshal.WriteRaw Shape_Tag where
writeRaw =
\ptr0 ->
\s1 ->
case s1 of
Shape_Tag unwrap2 ->
HsBindgen.Runtime.Marshal.writeRawByteOff ptr0 (0 :: Int) unwrap2
deriving via HsBindgen.Runtime.Marshal.EquivStorable Shape_Tag instance F.Storable Shape_Tag
deriving via FC.CUInt instance Data.Primitive.Types.Prim Shape_Tag
instance HsBindgen.Runtime.CEnum.CEnum Shape_Tag where
type CEnumZ Shape_Tag = FC.CUInt
toCEnum = Shape_Tag
fromCEnum = GHC.Records.getField @"unwrap"
declaredValues =
\_ ->
HsBindgen.Runtime.CEnum.declaredValuesFromList [ (0, Data.List.NonEmpty.singleton "Circle")
, (1, Data.List.NonEmpty.singleton "Rectangle")
]
showsUndeclared =
HsBindgen.Runtime.CEnum.showsWrappedUndeclared "Shape_Tag"
readPrecUndeclared =
HsBindgen.Runtime.CEnum.readPrecWrappedUndeclared "Shape_Tag"
isDeclared = HsBindgen.Runtime.CEnum.seqIsDeclared
mkDeclared = HsBindgen.Runtime.CEnum.seqMkDeclared
instance HsBindgen.Runtime.CEnum.SequentialCEnum Shape_Tag where
minDeclaredValue = Circle
maxDeclaredValue = Rectangle
instance Show Shape_Tag where
showsPrec = HsBindgen.Runtime.CEnum.shows
instance Read Shape_Tag where
readPrec = HsBindgen.Runtime.CEnum.readPrec
readList = Text.Read.readListDefault
readListPrec = Text.Read.readListPrecDefault
instance ( TyEq ty ((HsBindgen.Runtime.HasCField.CFieldType Shape_Tag) "unwrap")
) => GHC.Records.HasField "unwrap" (Ptr.Ptr Shape_Tag) (Ptr.Ptr ty) where
@ -151,32 +202,31 @@ instance ( TyEq ty ((HsBindgen.Runtime.HasCField.CFieldType Shape_Tag) "unwrap")
instance HsBindgen.Runtime.HasCField.HasCField Shape_Tag "unwrap" where
type CFieldType Shape_Tag "unwrap" =
HsBindgen.Runtime.LibC.Word8
type CFieldType Shape_Tag "unwrap" = FC.CUInt
offset# = \_ -> \_ -> 0
{-| __C declaration:__ @Circle@
__defined at:__ @garnet_rs.h 12:9@
__defined at:__ @garnet_rs.h 12:3@
__exported by:__ @garnet_rs.h@
-}
circle :: FC.CInt
circle = (0 :: FC.CInt)
pattern Circle :: Shape_Tag
pattern Circle = Shape_Tag 0
{-| __C declaration:__ @Rectangle@
__defined at:__ @garnet_rs.h 13:9@
__defined at:__ @garnet_rs.h 13:3@
__exported by:__ @garnet_rs.h@
-}
rectangle :: FC.CInt
rectangle = (1 :: FC.CInt)
pattern Rectangle :: Shape_Tag
pattern Rectangle = Shape_Tag 1
{-| __C declaration:__ @struct Circle_Body@
__defined at:__ @garnet_rs.h 15:16@
__defined at:__ @garnet_rs.h 16:8@
__exported by:__ @garnet_rs.h@
-}
@ -184,7 +234,7 @@ data Circle_Body = Circle_Body
{ radius :: FC.CDouble
{- ^ __C declaration:__ @radius@
__defined at:__ @garnet_rs.h 16:10@
__defined at:__ @garnet_rs.h 17:10@
__exported by:__ @garnet_rs.h@
-}
@ -230,7 +280,7 @@ instance ( TyEq ty ((HsBindgen.Runtime.HasCField.CFieldType Circle_Body) "radius
{-| __C declaration:__ @struct Rectangle_Body@
__defined at:__ @garnet_rs.h 19:16@
__defined at:__ @garnet_rs.h 20:8@
__exported by:__ @garnet_rs.h@
-}
@ -238,14 +288,14 @@ data Rectangle_Body = Rectangle_Body
{ width :: FC.CDouble
{- ^ __C declaration:__ @width@
__defined at:__ @garnet_rs.h 20:10@
__defined at:__ @garnet_rs.h 21:10@
__exported by:__ @garnet_rs.h@
-}
, height :: FC.CDouble
{- ^ __C declaration:__ @height@
__defined at:__ @garnet_rs.h 21:10@
__defined at:__ @garnet_rs.h 22:10@
__exported by:__ @garnet_rs.h@
-}
@ -305,7 +355,7 @@ instance ( TyEq ty ((HsBindgen.Runtime.HasCField.CFieldType Rectangle_Body) "hei
{-| __C declaration:__ @union \@Shape_body@
__defined at:__ @garnet_rs.h 26:3@
__defined at:__ @garnet_rs.h 27:3@
__exported by:__ @garnet_rs.h@
-}
@ -328,7 +378,7 @@ deriving via HsBindgen.Runtime.Marshal.EquivStorable Shape_body instance F.Stora
__C declaration:__ @circle@
__defined at:__ @garnet_rs.h 27:17@
__defined at:__ @garnet_rs.h 28:24@
__exported by:__ @garnet_rs.h@
-}
@ -355,7 +405,7 @@ set_shape_body_circle =
__C declaration:__ @rectangle@
__defined at:__ @garnet_rs.h 28:20@
__defined at:__ @garnet_rs.h 29:27@
__exported by:__ @garnet_rs.h@
-}
@ -403,7 +453,7 @@ instance ( TyEq ty ((HsBindgen.Runtime.HasCField.CFieldType Shape_body) "rectang
{-| __C declaration:__ @struct Shape@
__defined at:__ @garnet_rs.h 24:16@
__defined at:__ @garnet_rs.h 25:8@
__exported by:__ @garnet_rs.h@
-}
@ -411,14 +461,14 @@ data Shape = Shape
{ tag :: Shape_Tag
{- ^ __C declaration:__ @tag@
__defined at:__ @garnet_rs.h 25:13@
__defined at:__ @garnet_rs.h 26:18@
__exported by:__ @garnet_rs.h@
-}
, body :: Shape_body
{- ^ __C declaration:__ @body@
__defined at:__ @garnet_rs.h 29:5@
__defined at:__ @garnet_rs.h 30:5@
__exported by:__ @garnet_rs.h@
-}

View File

@ -44,9 +44,9 @@ $(HsBindgen.Runtime.Internal.CAPI.addCSource (HsBindgen.Runtime.Internal.CAPI.un
, "}"
, "/* com_garnet_GarnetRs_get_add */"
, "__attribute__ ((const))"
, "intptr_t (*hs_bindgen_bbabdbe61cd1eeb2 (void)) ("
, " intptr_t arg1,"
, " intptr_t arg2"
, "int64_t (*hs_bindgen_bbabdbe61cd1eeb2 (void)) ("
, " int64_t arg1,"
, " int64_t arg2"
, ")"
, "{"
, " return &add;"
@ -65,7 +65,7 @@ hs_bindgen_faf62265b53521d3 =
{-# NOINLINE hello #-}
{-| __C declaration:__ @hello@
__defined at:__ @garnet_rs.h 32:6@
__defined at:__ @garnet_rs.h 33:6@
__exported by:__ @garnet_rs.h@
-}
@ -85,7 +85,7 @@ hs_bindgen_0f8c37ef19b17a6d =
{-# NOINLINE hello_struct #-}
{-| __C declaration:__ @hello_struct@
__defined at:__ @garnet_rs.h 34:6@
__defined at:__ @garnet_rs.h 35:6@
__exported by:__ @garnet_rs.h@
-}
@ -105,7 +105,7 @@ hs_bindgen_287ff3ac660f333b =
{-# NOINLINE hello_shape #-}
{-| __C declaration:__ @hello_shape@
__defined at:__ @garnet_rs.h 36:6@
__defined at:__ @garnet_rs.h 37:6@
__exported by:__ @garnet_rs.h@
-}
@ -118,17 +118,17 @@ foreign import ccall unsafe "hs_bindgen_bbabdbe61cd1eeb2" hs_bindgen_bbabdbe61cd
IO (Ptr.FunPtr Void)
-- __unique:__ @com_garnet_GarnetRs_get_add@
hs_bindgen_bbabdbe61cd1eeb2 :: IO (Ptr.FunPtr (HsBindgen.Runtime.LibC.CIntPtr -> HsBindgen.Runtime.LibC.CIntPtr -> IO HsBindgen.Runtime.LibC.CIntPtr))
hs_bindgen_bbabdbe61cd1eeb2 :: IO (Ptr.FunPtr (HsBindgen.Runtime.LibC.Int64 -> HsBindgen.Runtime.LibC.Int64 -> IO HsBindgen.Runtime.LibC.Int64))
hs_bindgen_bbabdbe61cd1eeb2 =
HsBindgen.Runtime.Internal.HasFFIType.fromFFIType hs_bindgen_bbabdbe61cd1eeb2_base
{-# NOINLINE add #-}
{-| __C declaration:__ @add@
__defined at:__ @garnet_rs.h 38:10@
__defined at:__ @garnet_rs.h 39:32@
__exported by:__ @garnet_rs.h@
-}
add :: Ptr.FunPtr (HsBindgen.Runtime.LibC.CIntPtr -> HsBindgen.Runtime.LibC.CIntPtr -> IO HsBindgen.Runtime.LibC.CIntPtr)
add :: Ptr.FunPtr (HsBindgen.Runtime.LibC.Int64 -> HsBindgen.Runtime.LibC.Int64 -> IO HsBindgen.Runtime.LibC.Int64)
add =
GHC.IO.Unsafe.unsafePerformIO hs_bindgen_bbabdbe61cd1eeb2

View File

@ -37,9 +37,9 @@ $(HsBindgen.Runtime.Internal.CAPI.addCSource (HsBindgen.Runtime.Internal.CAPI.un
, "{"
, " hello_shape(*arg1);"
, "}"
, "intptr_t hs_bindgen_1c0c71fa74c428a9 ("
, " intptr_t arg1,"
, " intptr_t arg2"
, "int64_t hs_bindgen_1c0c71fa74c428a9 ("
, " int64_t arg1,"
, " int64_t arg2"
, ")"
, "{"
, " return add(arg1, arg2);"
@ -60,7 +60,7 @@ hs_bindgen_433ea2a26af4e593 =
{-| __C declaration:__ @hello@
__defined at:__ @garnet_rs.h 32:6@
__defined at:__ @garnet_rs.h 33:6@
__exported by:__ @garnet_rs.h@
-}
@ -84,7 +84,7 @@ hs_bindgen_51157946af5519c9 =
{-| __C declaration:__ @hello_struct@
__defined at:__ @garnet_rs.h 34:6@
__defined at:__ @garnet_rs.h 35:6@
__exported by:__ @garnet_rs.h@
-}
@ -110,7 +110,7 @@ hs_bindgen_7de06f1fd827ca60 =
{-| __C declaration:__ @hello_shape@
__defined at:__ @garnet_rs.h 36:6@
__defined at:__ @garnet_rs.h 37:6@
__exported by:__ @garnet_rs.h@
-}
@ -126,26 +126,30 @@ hello_shape =
foreign import ccall safe "hs_bindgen_1c0c71fa74c428a9" hs_bindgen_1c0c71fa74c428a9_base ::
GHC.Int.Int64
-> GHC.Int.Int64
-> IO GHC.Int.Int64
-> GHC.Int.Int64
-- __unique:__ @com_garnet_GarnetRs_Safe_add@
hs_bindgen_1c0c71fa74c428a9 ::
HsBindgen.Runtime.LibC.CIntPtr
-> HsBindgen.Runtime.LibC.CIntPtr
-> IO HsBindgen.Runtime.LibC.CIntPtr
HsBindgen.Runtime.LibC.Int64
-> HsBindgen.Runtime.LibC.Int64
-> HsBindgen.Runtime.LibC.Int64
hs_bindgen_1c0c71fa74c428a9 =
HsBindgen.Runtime.Internal.HasFFIType.fromFFIType hs_bindgen_1c0c71fa74c428a9_base
{-| __C declaration:__ @add@
{-|
__defined at:__ @garnet_rs.h 38:10@
Marked @__attribute((const))__@
__exported by:__ @garnet_rs.h@
__C declaration:__ @add@
__defined at:__ @garnet_rs.h 39:32@
__exported by:__ @garnet_rs.h@
-}
add ::
HsBindgen.Runtime.LibC.CIntPtr
HsBindgen.Runtime.LibC.Int64
-- ^ __C declaration:__ @a@
-> HsBindgen.Runtime.LibC.CIntPtr
-> HsBindgen.Runtime.LibC.Int64
-- ^ __C declaration:__ @b@
-> IO HsBindgen.Runtime.LibC.CIntPtr
-> HsBindgen.Runtime.LibC.Int64
add = hs_bindgen_1c0c71fa74c428a9

View File

@ -37,9 +37,9 @@ $(HsBindgen.Runtime.Internal.CAPI.addCSource (HsBindgen.Runtime.Internal.CAPI.un
, "{"
, " hello_shape(*arg1);"
, "}"
, "intptr_t hs_bindgen_20eb651f0a8faf48 ("
, " intptr_t arg1,"
, " intptr_t arg2"
, "int64_t hs_bindgen_20eb651f0a8faf48 ("
, " int64_t arg1,"
, " int64_t arg2"
, ")"
, "{"
, " return add(arg1, arg2);"
@ -60,7 +60,7 @@ hs_bindgen_2dfe97662a4d6377 =
{-| __C declaration:__ @hello@
__defined at:__ @garnet_rs.h 32:6@
__defined at:__ @garnet_rs.h 33:6@
__exported by:__ @garnet_rs.h@
-}
@ -84,7 +84,7 @@ hs_bindgen_29d823ada2bc7302 =
{-| __C declaration:__ @hello_struct@
__defined at:__ @garnet_rs.h 34:6@
__defined at:__ @garnet_rs.h 35:6@
__exported by:__ @garnet_rs.h@
-}
@ -110,7 +110,7 @@ hs_bindgen_b3f40a03f07eaa85 =
{-| __C declaration:__ @hello_shape@
__defined at:__ @garnet_rs.h 36:6@
__defined at:__ @garnet_rs.h 37:6@
__exported by:__ @garnet_rs.h@
-}
@ -126,26 +126,30 @@ hello_shape =
foreign import ccall unsafe "hs_bindgen_20eb651f0a8faf48" hs_bindgen_20eb651f0a8faf48_base ::
GHC.Int.Int64
-> GHC.Int.Int64
-> IO GHC.Int.Int64
-> GHC.Int.Int64
-- __unique:__ @com_garnet_GarnetRs_Unsafe_add@
hs_bindgen_20eb651f0a8faf48 ::
HsBindgen.Runtime.LibC.CIntPtr
-> HsBindgen.Runtime.LibC.CIntPtr
-> IO HsBindgen.Runtime.LibC.CIntPtr
HsBindgen.Runtime.LibC.Int64
-> HsBindgen.Runtime.LibC.Int64
-> HsBindgen.Runtime.LibC.Int64
hs_bindgen_20eb651f0a8faf48 =
HsBindgen.Runtime.Internal.HasFFIType.fromFFIType hs_bindgen_20eb651f0a8faf48_base
{-| __C declaration:__ @add@
{-|
__defined at:__ @garnet_rs.h 38:10@
Marked @__attribute((const))__@
__exported by:__ @garnet_rs.h@
__C declaration:__ @add@
__defined at:__ @garnet_rs.h 39:32@
__exported by:__ @garnet_rs.h@
-}
add ::
HsBindgen.Runtime.LibC.CIntPtr
HsBindgen.Runtime.LibC.Int64
-- ^ __C declaration:__ @a@
-> HsBindgen.Runtime.LibC.CIntPtr
-> HsBindgen.Runtime.LibC.Int64
-- ^ __C declaration:__ @b@
-> IO HsBindgen.Runtime.LibC.CIntPtr
-> HsBindgen.Runtime.LibC.Int64
add = hs_bindgen_20eb651f0a8faf48

View File

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

View File

@ -22,7 +22,7 @@ extern "C" fn hello_struct(t: T) -> () {
say_hello(&format!("{:?}", t))
}
#[repr(C, u8)]
#[repr(C)]
#[derive(Debug)]
enum Shape {
Circle { radius: f64 },
@ -34,7 +34,8 @@ extern "C" fn hello_shape(s: Shape) -> () {
say_hello(&format!("{:?}", s))
}
/// cbindgen:prefix=__attribute__((const))
#[unsafe(no_mangle)]
extern "C" fn add(a: isize, b: isize) -> isize {
extern "C" fn add(a: i64, b: i64) -> i64 {
a + b
}