mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-08 04:53:42 +00:00
cgo: implement C unions
Unions are somewhat hard to implement in Go because they are not a native type. But it is actually possible with some compiler magic. This commit inserts a special "C union" field at the start of a struct to indicate that it is a union. As such a field cannot be written directly in Go, this is a useful to distinguish structs and unions.
This commit is contained in:
committed by
Ron Evans
parent
536086988c
commit
d2b3a5486c
Vendored
+18
-1
@@ -8,8 +8,11 @@ double globalDouble = 3.2;
|
||||
_Complex float globalComplexFloat = 4.1+3.3i;
|
||||
_Complex double globalComplexDouble = 4.2+3.4i;
|
||||
_Complex double globalComplexLongDouble = 4.3+3.5i;
|
||||
collection_t globalStruct = {256, -123456, 3.14};
|
||||
collection_t globalStruct = {256, -123456, 3.14, 88};
|
||||
int globalStructSize = sizeof(globalStruct);
|
||||
short globalArray[3] = {5, 6, 7};
|
||||
joined_t globalUnion;
|
||||
int globalUnionSize = sizeof(globalUnion);
|
||||
|
||||
int fortytwo() {
|
||||
return 42;
|
||||
@@ -26,3 +29,17 @@ int doCallback(int a, int b, binop_t callback) {
|
||||
void store(int value, int *ptr) {
|
||||
*ptr = value;
|
||||
}
|
||||
|
||||
void unionSetShort(short s) {
|
||||
globalUnion.s = s;
|
||||
}
|
||||
|
||||
void unionSetFloat(float f) {
|
||||
globalUnion.f = f;
|
||||
}
|
||||
|
||||
void unionSetData(short f0, short f1, short f2) {
|
||||
globalUnion.data[0] = 5;
|
||||
globalUnion.data[1] = 8;
|
||||
globalUnion.data[2] = 1;
|
||||
}
|
||||
|
||||
Vendored
+24
-1
@@ -9,6 +9,10 @@ import "C"
|
||||
|
||||
import "unsafe"
|
||||
|
||||
func (s C.myint) Int() int {
|
||||
return int(s)
|
||||
}
|
||||
|
||||
func main() {
|
||||
println("fortytwo:", C.fortytwo())
|
||||
println("add:", C.add(C.int(3), 5))
|
||||
@@ -36,9 +40,28 @@ func main() {
|
||||
println("complex float:", C.globalComplexFloat)
|
||||
println("complex double:", C.globalComplexDouble)
|
||||
println("complex long double:", C.globalComplexLongDouble)
|
||||
println("struct:", C.globalStruct.s, C.globalStruct.l, C.globalStruct.f)
|
||||
|
||||
// complex types
|
||||
println("struct:", C.int(unsafe.Sizeof(C.globalStruct)) == C.globalStructSize, C.globalStruct.s, C.globalStruct.l, C.globalStruct.f)
|
||||
var _ [3]C.short = C.globalArray
|
||||
println("array:", C.globalArray[0], C.globalArray[1], C.globalArray[2])
|
||||
println("union:", C.int(unsafe.Sizeof(C.globalUnion)) == C.globalUnionSize)
|
||||
C.unionSetShort(22)
|
||||
println("union s:", C.globalUnion.s)
|
||||
C.unionSetFloat(3.14)
|
||||
println("union f:", C.globalUnion.f)
|
||||
C.unionSetData(5, 8, 1)
|
||||
println("union global data:", C.globalUnion.data[0], C.globalUnion.data[1], C.globalUnion.data[2])
|
||||
println("union field:", printUnion(C.globalUnion).f)
|
||||
}
|
||||
|
||||
func printUnion(union C.joined_t) C.joined_t {
|
||||
println("union local data: ", union.data[0], union.data[1], union.data[2])
|
||||
union.s = -33
|
||||
println("union s method:", union.s.Int(), union.data[0] == 5)
|
||||
union.f = 6.28
|
||||
println("union f:", union.f)
|
||||
return union
|
||||
}
|
||||
|
||||
//export mul
|
||||
|
||||
Vendored
+16
-3
@@ -6,11 +6,21 @@ typedef int * intPointer;
|
||||
void store(int value, int *ptr);
|
||||
|
||||
typedef struct collection {
|
||||
short s;
|
||||
long l;
|
||||
float f;
|
||||
short s;
|
||||
long l;
|
||||
float f;
|
||||
unsigned char c;
|
||||
} collection_t;
|
||||
|
||||
typedef union joined {
|
||||
myint s;
|
||||
float f;
|
||||
short data[3];
|
||||
} joined_t;
|
||||
void unionSetShort(short s);
|
||||
void unionSetFloat(float f);
|
||||
void unionSetData(short f0, short f1, short f2);
|
||||
|
||||
// test globals
|
||||
extern int global;
|
||||
extern _Bool globalBool;
|
||||
@@ -21,7 +31,10 @@ extern _Complex float globalComplexFloat;
|
||||
extern _Complex double globalComplexDouble;
|
||||
extern _Complex double globalComplexLongDouble;
|
||||
extern collection_t globalStruct;
|
||||
extern int globalStructSize;
|
||||
extern short globalArray[3];
|
||||
extern joined_t globalUnion;
|
||||
extern int globalUnionSize;
|
||||
|
||||
// test duplicate definitions
|
||||
int add(int a, int b);
|
||||
|
||||
Vendored
+10
@@ -14,3 +14,13 @@ double: +3.200000e+000
|
||||
complex float: (+4.100000e+000+3.300000e+000i)
|
||||
complex double: (+4.200000e+000+3.400000e+000i)
|
||||
complex long double: (+4.300000e+000+3.500000e+000i)
|
||||
struct: true 256 -123456 +3.140000e+000
|
||||
array: 5 6 7
|
||||
union: true
|
||||
union s: 22
|
||||
union f: +3.140000e+000
|
||||
union global data: 5 8 1
|
||||
union local data: 5 8 1
|
||||
union s method: -33 false
|
||||
union f: +6.280000e+000
|
||||
union field: +6.280000e+000
|
||||
|
||||
Reference in New Issue
Block a user