- Structs are converted to opaque types
- Unions are converted to opaque types
- Simple functions are converted to direct `@extern` functions
- Problematic functions generate C forwarders
- Enums are generated for specific C type
- Function pointers are defined as opaque types
- Recursive structs are rewritten with opaque pointers
- Global enums are rendered as constants
- Anonymous unions/structs are fully qualified and rendered separately
Structs are converted to opaque types
For those types, we generate getters, setters, Tag definition, and two apply methods:
- A constructor, which takes all the parameters as arguments
- An allocator, which only creates an instance on the heap, without initialising it
Source C code
typedef struct {
long long number;
} Small;
typedef struct {
int x;
char* hello;
Small sm;
} Big;
Generated Scala code
package libtest
import _root_.scala.scalanative.unsafe.*
import _root_.scala.scalanative.unsigned.*
import _root_.scala.scalanative.libc.*
import _root_.scala.scalanative.*
object structs:
import _root_.libtest.structs.*
opaque type Big = CStruct3[CInt, CString, Small]
object Big:
given _tag: Tag[Big] = Tag.materializeCStruct3Tag[CInt, CString, Small]
export fields.*
private[libtest] object fields:
extension (struct: Big)
inline def x : CInt = struct._1
inline def x_=(value: CInt): Unit = (!struct.at1 = value)
inline def hello : CString = struct._2
inline def hello_=(value: CString): Unit = (!struct.at2 = value)
inline def sm : Small = struct._3
inline def sm_=(value: Small): Unit = (!struct.at3 = value)
end extension
// Allocates Big on the heap ??? fields are not initalised or zeroed out
def apply()(using Zone): Ptr[Big] = scala.scalanative.unsafe.alloc[Big](1)
def apply(x : CInt, hello : CString, sm : Small)(using Zone): Ptr[Big] =
val ____ptr = apply()
(!____ptr).x = x
(!____ptr).hello = hello
(!____ptr).sm = sm
____ptr
opaque type Small = CStruct1[CLongLong]
object Small:
given _tag: Tag[Small] = Tag.materializeCStruct1Tag[CLongLong]
export fields.*
private[libtest] object fields:
extension (struct: Small)
inline def number : CLongLong = struct._1
inline def number_=(value: CLongLong): Unit = (!struct.at1 = value)
end extension
// Allocates Small on the heap ??? fields are not initalised or zeroed out
def apply()(using Zone): Ptr[Small] = scala.scalanative.unsafe.alloc[Small](1)
def apply(number : CLongLong)(using Zone): Ptr[Small] =
val ____ptr = apply()
(!____ptr).number = number
____ptr
object types:
export _root_.libtest.structs.*
object all:
export _root_.libtest.structs.Big
export _root_.libtest.structs.Small
You can disable constructor generation
Some bindings (libnotify, gtk, nuklear) have such deep type hierarchies, that apply methods on some structs trigger an exception during bytecode generation (when compiling the generated code):
java.lang.IllegalArgumentException: UTF8 string too large
To work around it, you can disable constructor generation by passing a comma-separated
list of struct names using the --render.no-constructor option in CLI, and noConstructor
parameter in the Binding(...) specification.
Source C code
typedef struct {
int x;
char* hello;
} Enabled;
typedef struct {
int x;
char* hello;
} Disabled;
Generated Scala code
package libtest
import _root_.scala.scalanative.unsafe.*
import _root_.scala.scalanative.unsigned.*
import _root_.scala.scalanative.libc.*
import _root_.scala.scalanative.*
object structs:
import _root_.libtest.structs.*
opaque type Disabled = CStruct2[CInt, CString]
object Disabled:
given _tag: Tag[Disabled] = Tag.materializeCStruct2Tag[CInt, CString]
export fields.*
private[libtest] object fields:
extension (struct: Disabled)
inline def x : CInt = struct._1
inline def x_=(value: CInt): Unit = (!struct.at1 = value)
inline def hello : CString = struct._2
inline def hello_=(value: CString): Unit = (!struct.at2 = value)
end extension
// Allocates Disabled on the heap ??? fields are not initalised or zeroed out
def apply()(using Zone): Ptr[Disabled] = scala.scalanative.unsafe.alloc[Disabled](1)
opaque type Enabled = CStruct2[CInt, CString]
object Enabled:
given _tag: Tag[Enabled] = Tag.materializeCStruct2Tag[CInt, CString]
export fields.*
private[libtest] object fields:
extension (struct: Enabled)
inline def x : CInt = struct._1
inline def x_=(value: CInt): Unit = (!struct.at1 = value)
inline def hello : CString = struct._2
inline def hello_=(value: CString): Unit = (!struct.at2 = value)
end extension
// Allocates Enabled on the heap ??? fields are not initalised or zeroed out
def apply()(using Zone): Ptr[Enabled] = scala.scalanative.unsafe.alloc[Enabled](1)
def apply(x : CInt, hello : CString)(using Zone): Ptr[Enabled] =
val ____ptr = apply()
(!____ptr).x = x
(!____ptr).hello = hello
____ptr
object types:
export _root_.libtest.structs.*
object all:
export _root_.libtest.structs.Disabled
export _root_.libtest.structs.Enabled
Unions are converted to opaque types
For a union with N members, N constructors will be generated,
along with getters and setters.
Source C code
typedef struct {
long long number;
} Small;
typedef union {
int x;
char* hello;
Small sm;
} Big;
Generated Scala code
package libtest
import _root_.scala.scalanative.unsafe.*
import _root_.scala.scalanative.unsigned.*
import _root_.scala.scalanative.libc.*
import _root_.scala.scalanative.*
object structs:
import _root_.libtest.structs.*
import _root_.libtest.unions.*
opaque type Small = CStruct1[CLongLong]
object Small:
given _tag: Tag[Small] = Tag.materializeCStruct1Tag[CLongLong]
export fields.*
private[libtest] object fields:
extension (struct: Small)
inline def number : CLongLong = struct._1
inline def number_=(value: CLongLong): Unit = (!struct.at1 = value)
end extension
// Allocates Small on the heap ??? fields are not initalised or zeroed out
def apply()(using Zone): Ptr[Small] = scala.scalanative.unsafe.alloc[Small](1)
def apply(number : CLongLong)(using Zone): Ptr[Small] =
val ____ptr = apply()
(!____ptr).number = number
____ptr
object unions:
import _root_.libtest.structs.*
import _root_.libtest.unions.*
opaque type Big = CArray[Byte, Nat._8]
object Big:
given _tag: Tag[Big] = Tag.CArray[CChar, Nat._8](Tag.Byte, Tag.Nat8)
def apply()(using Zone): Ptr[Big] =
val ___ptr = _root_.scala.scalanative.unsafe.alloc[Big](1)
___ptr
@scala.annotation.targetName("apply_x")
def apply(x: CInt)(using Zone): Ptr[Big] =
val ___ptr = _root_.scala.scalanative.unsafe.alloc[Big](1)
val un = !___ptr
un.at(0).asInstanceOf[Ptr[CInt]].update(0, x)
___ptr
@scala.annotation.targetName("apply_hello")
def apply(hello: CString)(using Zone): Ptr[Big] =
val ___ptr = _root_.scala.scalanative.unsafe.alloc[Big](1)
val un = !___ptr
un.at(0).asInstanceOf[Ptr[CString]].update(0, hello)
___ptr
@scala.annotation.targetName("apply_sm")
def apply(sm: Small)(using Zone): Ptr[Big] =
val ___ptr = _root_.scala.scalanative.unsafe.alloc[Big](1)
val un = !___ptr
un.at(0).asInstanceOf[Ptr[Small]].update(0, sm)
___ptr
extension (struct: Big)
inline def x : CInt = !struct.at(0).asInstanceOf[Ptr[CInt]]
inline def x_=(value: CInt): Unit = !struct.at(0).asInstanceOf[Ptr[CInt]] = value
inline def hello : CString = !struct.at(0).asInstanceOf[Ptr[CString]]
inline def hello_=(value: CString): Unit = !struct.at(0).asInstanceOf[Ptr[CString]] = value
inline def sm : Small = !struct.at(0).asInstanceOf[Ptr[Small]]
inline def sm_=(value: Small): Unit = !struct.at(0).asInstanceOf[Ptr[Small]] = value
object types:
export _root_.libtest.structs.*
export _root_.libtest.unions.*
object all:
export _root_.libtest.structs.Small
export _root_.libtest.unions.Big
Simple functions are converted to direct @extern functions
Where "Simple" means "not passing naked structs", because Scala Native cannot handle that (passing by pointer is okay)
Source C code
typedef struct {
long long number;
} Small;
long simple(int x, char *y);
Small* with_pointers(Small *x, int y);
Generated Scala code
package libtest
import _root_.scala.scalanative.unsafe.*
import _root_.scala.scalanative.unsigned.*
import _root_.scala.scalanative.libc.*
import _root_.scala.scalanative.*
object structs:
import _root_.libtest.structs.*
opaque type Small = CStruct1[CLongLong]
object Small:
given _tag: Tag[Small] = Tag.materializeCStruct1Tag[CLongLong]
export fields.*
private[libtest] object fields:
extension (struct: Small)
inline def number : CLongLong = struct._1
inline def number_=(value: CLongLong): Unit = (!struct.at1 = value)
end extension
// Allocates Small on the heap ??? fields are not initalised or zeroed out
def apply()(using Zone): Ptr[Small] = scala.scalanative.unsafe.alloc[Small](1)
def apply(number : CLongLong)(using Zone): Ptr[Small] =
val ____ptr = apply()
(!____ptr).number = number
____ptr
@extern
private[libtest] object extern_functions:
import _root_.libtest.structs.*
def simple(x : CInt, y : CString): CLongInt = extern
def with_pointers(x : Ptr[Small], y : CInt): Ptr[Small] = extern
object functions:
import _root_.libtest.structs.*
import extern_functions.*
export extern_functions.*
object types:
export _root_.libtest.structs.*
object all:
export _root_.libtest.structs.Small
export _root_.libtest.functions.simple
export _root_.libtest.functions.with_pointers
Problematic functions generate C forwarders
Where "Problematic" means having a struct as one of its arguments or return type. In this case we generate several variations of public Scala functions, but they all delegate to an external C function which takes its arguments as pointers, and (optionally) returns its value in a provided heap-allocated location.
Source C code
typedef struct {
long long number;
} Small;
void bad_arguments(Small n, Small n2);
Small bad_return_type();
Generated Scala code
package libtest
import _root_.scala.scalanative.unsafe.*
import _root_.scala.scalanative.unsigned.*
import _root_.scala.scalanative.libc.*
import _root_.scala.scalanative.*
object structs:
import _root_.libtest.structs.*
opaque type Small = CStruct1[CLongLong]
object Small:
given _tag: Tag[Small] = Tag.materializeCStruct1Tag[CLongLong]
export fields.*
private[libtest] object fields:
extension (struct: Small)
inline def number : CLongLong = struct._1
inline def number_=(value: CLongLong): Unit = (!struct.at1 = value)
end extension
// Allocates Small on the heap ??? fields are not initalised or zeroed out
def apply()(using Zone): Ptr[Small] = scala.scalanative.unsafe.alloc[Small](1)
def apply(number : CLongLong)(using Zone): Ptr[Small] =
val ____ptr = apply()
(!____ptr).number = number
____ptr
@extern
private[libtest] object extern_functions:
import _root_.libtest.structs.*
private[libtest] def __sn_wrap_libtest_bad_arguments(n : Ptr[Small], n2 : Ptr[Small]): Unit = extern
private[libtest] def __sn_wrap_libtest_bad_return_type(__return : Ptr[Small]): Unit = extern
object functions:
import _root_.libtest.structs.*
import extern_functions.*
export extern_functions.*
def bad_arguments(n : Small, n2 : Small)(using Zone): Unit =
val __ptr_0: Ptr[Small] = _root_.scala.scalanative.unsafe.alloc[Small](2)
!(__ptr_0 + 0) = n
!(__ptr_0 + 1) = n2
__sn_wrap_libtest_bad_arguments((__ptr_0 + 0), (__ptr_0 + 1))
def bad_arguments(n : Ptr[Small], n2 : Ptr[Small]): Unit =
__sn_wrap_libtest_bad_arguments(n, n2)
def bad_return_type()(using Zone): Small =
val __ptr_0: Ptr[Small] = _root_.scala.scalanative.unsafe.alloc[Small](1)
__sn_wrap_libtest_bad_return_type((__ptr_0 + 0))
!(__ptr_0 + 0)
def bad_return_type()(__return : Ptr[Small]): Unit =
__sn_wrap_libtest_bad_return_type(__return)
object types:
export _root_.libtest.structs.*
object all:
export _root_.libtest.structs.Small
export _root_.libtest.functions.bad_arguments
export _root_.libtest.functions.bad_return_type
Generated C code
#include <string.h>
void __sn_wrap_libtest_bad_arguments(Small *n, Small *n2) {
bad_arguments(*n, *n2);
};
void __sn_wrap_libtest_bad_return_type(Small *____return) {
Small ____ret = bad_return_type();
memcpy(____return, &____ret, sizeof(Small));
}
Enums are generated for specific C type
Whatever type clang reports for a particular enum - that's the type that will be used for the enum.
This is important, as on Windows enums are int by default, whereas on Linux and OS X they are unsigned int (if there's no negative elements).
This documentation is built on Linux.
Source C code
typedef enum {
U_X = 1,
U_Y = 4,
U_Z = 228
} MyUnsigned;
typedef enum {
X = -1,
Y = 4,
Z = 228
} MySigned;
Generated Scala code
package libtest
import _root_.scala.scalanative.unsafe.*
import _root_.scala.scalanative.unsigned.*
import _root_.scala.scalanative.libc.*
import _root_.scala.scalanative.*
object predef:
private[libtest] trait _BindgenEnumCInt[T](using eq: T =:= CInt):
given Tag[T] = Tag.Int.asInstanceOf[Tag[T]]
extension (inline t: T)
inline def value: CInt = t.asInstanceOf[CInt]
inline def int: CInt = value.toInt
private[libtest] trait _BindgenEnumCUnsignedInt[T](using eq: T =:= CUnsignedInt):
given Tag[T] = Tag.UInt.asInstanceOf[Tag[T]]
extension (inline t: T)
inline def value: CUnsignedInt = t.asInstanceOf[CUnsignedInt]
inline def int: CInt = value.toInt
inline def uint: CUnsignedInt = value
object enumerations:
import predef.*
opaque type MySigned = CInt
object MySigned extends _BindgenEnumCInt[MySigned]:
given _tag: Tag[MySigned] = Tag.Int
inline def define(inline a: CInt): MySigned = a
val X = define(-1)
val Y = define(4)
val Z = define(228)
def getName(value: MySigned): Option[String] =
value match
case `X` => Some("X")
case `Y` => Some("Y")
case `Z` => Some("Z")
case _ => _root_.scala.None
extension (a: MySigned)
inline def &(b: MySigned): MySigned = a & b
inline def |(b: MySigned): MySigned = a | b
inline def is(b: MySigned): Boolean = (a & b) == b
opaque type MyUnsigned = CUnsignedInt
object MyUnsigned extends _BindgenEnumCUnsignedInt[MyUnsigned]:
given _tag: Tag[MyUnsigned] = Tag.UInt
inline def define(inline a: Long): MyUnsigned = a.toUInt
val U_X = define(1)
val U_Y = define(4)
val U_Z = define(228)
def getName(value: MyUnsigned): Option[String] =
value match
case `U_X` => Some("U_X")
case `U_Y` => Some("U_Y")
case `U_Z` => Some("U_Z")
case _ => _root_.scala.None
extension (a: MyUnsigned)
inline def &(b: MyUnsigned): MyUnsigned = a & b
inline def |(b: MyUnsigned): MyUnsigned = a | b
inline def is(b: MyUnsigned): Boolean = (a & b) == b
object types:
export _root_.libtest.enumerations.*
object all:
export _root_.libtest.enumerations.MySigned
export _root_.libtest.enumerations.MyUnsigned
Function pointers are defined as opaque types
The inlining in apply method is important - it's a restricting of Scala Native
that the function must be statically known.
Source C code
typedef void* Cursor;
typedef int (*Visitor)(Cursor*);
Generated Scala code
package libtest
import _root_.scala.scalanative.unsafe.*
import _root_.scala.scalanative.unsigned.*
import _root_.scala.scalanative.libc.*
import _root_.scala.scalanative.*
object aliases:
import _root_.libtest.aliases.*
opaque type Cursor = Ptr[Byte]
object Cursor:
given _tag: Tag[Cursor] = Tag.Ptr(Tag.Byte)
inline def apply(inline o: Ptr[Byte]): Cursor = o
extension (v: Cursor)
inline def value: Ptr[Byte] = v
opaque type Visitor = CFuncPtr1[Ptr[Cursor], CInt]
object Visitor:
given _tag: Tag[Visitor] = Tag.materializeCFuncPtr1[Ptr[Cursor], CInt]
inline def fromPtr(ptr: Ptr[Byte] | CVoidPtr): Visitor = CFuncPtr.fromPtr(ptr.asInstanceOf[Ptr[Byte]])
inline def apply(inline o: CFuncPtr1[Ptr[Cursor], CInt]): Visitor = o
extension (v: Visitor)
inline def value: CFuncPtr1[Ptr[Cursor], CInt] = v
inline def toPtr: CVoidPtr = CFuncPtr.toPtr(v)
object types:
export _root_.libtest.aliases.*
object all:
export _root_.libtest.aliases.Cursor
export _root_.libtest.aliases.Visitor
Recursive structs are rewritten with opaque pointers
This is invisible to the user, so doesn't impact the experience, but can complicate reading the code.
Scala cannot have recursive type aliases.
Source C code
typedef struct Arr;
typedef struct {
struct Arr* nested;
} Arr;
Generated Scala code
package libtest
import _root_.scala.scalanative.unsafe.*
import _root_.scala.scalanative.unsigned.*
import _root_.scala.scalanative.libc.*
import _root_.scala.scalanative.*
object structs:
import _root_.libtest.structs.*
opaque type Arr = CStruct1[Ptr[Byte]]
object Arr:
given _tag: Tag[Arr] = Tag.materializeCStruct1Tag[Ptr[Byte]]
export fields.*
private[libtest] object fields:
extension (struct: Arr)
inline def nested : Ptr[Arr] = struct._1.asInstanceOf[Ptr[Arr]]
inline def nested_=(value: Ptr[Arr]): Unit = (!struct.at1 = value.asInstanceOf[Ptr[Byte]])
end extension
// Allocates Arr on the heap ??? fields are not initalised or zeroed out
def apply()(using Zone): Ptr[Arr] = scala.scalanative.unsafe.alloc[Arr](1)
def apply(nested : Ptr[Arr])(using Zone): Ptr[Arr] =
val ____ptr = apply()
(!____ptr).nested = nested
____ptr
object types:
export _root_.libtest.structs.*
object all:
export _root_.libtest.structs.Arr
Global enums are rendered as constants
Source C code
enum {
HELLO = 25,
BYEBYE = 11
};
enum {
HOW=-1,
DOESTHIS=-2,
WORK=0
};
Generated Scala code
package libtest
import _root_.scala.scalanative.unsafe.*
import _root_.scala.scalanative.unsigned.*
import _root_.scala.scalanative.libc.*
import _root_.scala.scalanative.*
object constants:
val HELLO: CUnsignedInt = 25.toUInt
val BYEBYE: CUnsignedInt = 11.toUInt
val HOW: CInt = -1
val DOESTHIS: CInt = -2
val WORK: CInt = 0
Anonymous unions/structs are fully qualified and rendered separately
In this example, we have several anonymous definitions as part of the struct.
If the anonymous union/struct/enum is attached to a named field, that field's name will be used as heuristic for naming the anonymous definition.
Otherwise, Union0, Struct1, etc. naming scheme will be used.
In the example below, StructExample_Greeting, StructExample_Test, StructExample_Hello,
and StructExample_Union0 will be generated
Deep field access (e.g. calling .x on StructExample directly, like what C allows, is not supported yet,
but planned.
Source C code
typedef struct {
struct {int hello;} greeting;
union {int x;};
union {char z;} *test;
enum {A, B, C} hello;
} StructExample;
Generated Scala code
package libtest
import _root_.scala.scalanative.unsafe.*
import _root_.scala.scalanative.unsigned.*
import _root_.scala.scalanative.libc.*
import _root_.scala.scalanative.*
object predef:
private[libtest] trait _BindgenEnumCUnsignedInt[T](using eq: T =:= CUnsignedInt):
given Tag[T] = Tag.UInt.asInstanceOf[Tag[T]]
extension (inline t: T)
inline def value: CUnsignedInt = t.asInstanceOf[CUnsignedInt]
inline def int: CInt = value.toInt
inline def uint: CUnsignedInt = value
object structs:
import _root_.libtest.predef.*
import _root_.libtest.structs.*
opaque type StructExample = CStruct4[StructExample_Greeting, StructExample_Union0, Ptr[StructExample_Test], StructExample_Hello]
object StructExample:
given _tag: Tag[StructExample] = Tag.materializeCStruct4Tag[StructExample_Greeting, StructExample_Union0, Ptr[StructExample_Test], StructExample_Hello]
export fields.*
private[libtest] object fields:
extension (struct: StructExample)
inline def greeting : StructExample_Greeting = struct._1
inline def greeting_=(value: StructExample_Greeting): Unit = (!struct.at1 = value)
inline def _2 : StructExample_Union0 = struct._2
inline def _2_=(value: StructExample_Union0): Unit = (!struct.at2 = value)
inline def test : Ptr[StructExample_Test] = struct._3
inline def test_=(value: Ptr[StructExample_Test]): Unit = (!struct.at3 = value)
inline def hello : StructExample_Hello = struct._4
inline def hello_=(value: StructExample_Hello): Unit = (!struct.at4 = value)
end extension
// Allocates StructExample on the heap ??? fields are not initalised or zeroed out
def apply()(using Zone): Ptr[StructExample] = scala.scalanative.unsafe.alloc[StructExample](1)
def apply(greeting : StructExample_Greeting, _2 : StructExample_Union0, test : Ptr[StructExample_Test], hello : StructExample_Hello)(using Zone): Ptr[StructExample] =
val ____ptr = apply()
(!____ptr).greeting = greeting
(!____ptr)._2 = _2
(!____ptr).test = test
(!____ptr).hello = hello
____ptr
opaque type StructExample_Greeting = CStruct1[CInt]
object StructExample_Greeting:
given _tag: Tag[StructExample_Greeting] = Tag.materializeCStruct1Tag[CInt]
export fields.*
private[libtest] object fields:
extension (struct: StructExample_Greeting)
inline def hello : CInt = struct._1
inline def hello_=(value: CInt): Unit = (!struct.at1 = value)
end extension
// Allocates StructExample_Greeting on the heap ??? fields are not initalised or zeroed out
def apply()(using Zone): Ptr[StructExample_Greeting] = scala.scalanative.unsafe.alloc[StructExample_Greeting](1)
def apply(hello : CInt)(using Zone): Ptr[StructExample_Greeting] =
val ____ptr = apply()
(!____ptr).hello = hello
____ptr
opaque type StructExample_Union0 = CArray[Byte, Nat._4]
object StructExample_Union0:
given _tag: Tag[StructExample_Union0] = Tag.CArray[CChar, Nat._4](Tag.Byte, Tag.Nat4)
def apply()(using Zone): Ptr[StructExample_Union0] =
val ___ptr = _root_.scala.scalanative.unsafe.alloc[StructExample_Union0](1)
___ptr
@scala.annotation.targetName("apply_x")
def apply(x: CInt)(using Zone): Ptr[StructExample_Union0] =
val ___ptr = _root_.scala.scalanative.unsafe.alloc[StructExample_Union0](1)
val un = !___ptr
un.at(0).asInstanceOf[Ptr[CInt]].update(0, x)
___ptr
extension (struct: StructExample_Union0)
inline def x : CInt = !struct.at(0).asInstanceOf[Ptr[CInt]]
inline def x_=(value: CInt): Unit = !struct.at(0).asInstanceOf[Ptr[CInt]] = value
opaque type StructExample_Test = CArray[Byte, Nat._1]
object StructExample_Test:
given _tag: Tag[StructExample_Test] = Tag.CArray[CChar, Nat._1](Tag.Byte, Tag.Nat1)
def apply()(using Zone): Ptr[StructExample_Test] =
val ___ptr = _root_.scala.scalanative.unsafe.alloc[StructExample_Test](1)
___ptr
@scala.annotation.targetName("apply_z")
def apply(z: CChar)(using Zone): Ptr[StructExample_Test] =
val ___ptr = _root_.scala.scalanative.unsafe.alloc[StructExample_Test](1)
val un = !___ptr
un.at(0).asInstanceOf[Ptr[CChar]].update(0, z)
___ptr
extension (struct: StructExample_Test)
inline def z : CChar = !struct.at(0).asInstanceOf[Ptr[CChar]]
inline def z_=(value: CChar): Unit = !struct.at(0).asInstanceOf[Ptr[CChar]] = value
opaque type StructExample_Hello = CUnsignedInt
object StructExample_Hello extends _BindgenEnumCUnsignedInt[StructExample_Hello]:
given _tag: Tag[StructExample_Hello] = Tag.UInt
inline def define(inline a: Long): StructExample_Hello = a.toUInt
val A = define(0)
val B = define(1)
val C = define(2)
def getName(value: StructExample_Hello): Option[String] =
value match
case `A` => Some("A")
case `B` => Some("B")
case `C` => Some("C")
case _ => _root_.scala.None
extension (a: StructExample_Hello)
inline def &(b: StructExample_Hello): StructExample_Hello = a & b
inline def |(b: StructExample_Hello): StructExample_Hello = a | b
inline def is(b: StructExample_Hello): Boolean = (a & b) == b
object constants:
val A: CUnsignedInt = 0.toUInt
val B: CUnsignedInt = 1.toUInt
val C: CUnsignedInt = 2.toUInt
object types:
export _root_.libtest.structs.*
object all:
export _root_.libtest.structs.StructExample