tinygo/testdata/cgo/main.go
Ayke van Laethem f316ebc23b all: include picolibc for bare metal targets
This is necessary for better CGo support on bare metal. Existing
libraries expect to be able to include parts of libc and expect to be
able to link to those symbols.

Because with this all targets have a working libc, it is now possible to
add tests to check that a libc in fact works basically.

Not all parts of picolibc are included, such as the math or stdio parts.
These should be added later, when needed.

This commit also avoids the need for the custom memcpy/memset/memcmp
symbols that are sometimes emitted by LLVM. The C library will take care
of that.
2020-03-22 17:14:59 +01:00

142 строки
4,3 КиБ
Go

package main
/*
int fortytwo(void);
#include "main.h"
int mul(int, int);
#include <string.h>
*/
import "C"
import "C"
import "unsafe"
func main() {
println("fortytwo:", C.fortytwo())
println("add:", C.add(C.int(3), 5))
var x C.myint = 3
println("myint:", x, C.myint(5))
println("myint size:", int(unsafe.Sizeof(x)))
var y C.longlong = -(1 << 40)
println("longlong:", y)
println("global:", C.global)
println("defined ints:", C.CONST_INT, C.CONST_INT2)
println("defined floats:", C.CONST_FLOAT, C.CONST_FLOAT2)
println("defined string:", C.CONST_STRING)
println("defined char:", C.CONST_CHAR)
var ptr C.intPointer
var n C.int = 15
ptr = C.intPointer(&n)
println("15:", *ptr)
C.store(25, &n)
println("25:", *ptr)
cb := C.binop_t(C.add)
println("callback 1:", C.doCallback(20, 30, cb))
cb = C.binop_t(C.mul)
println("callback 2:", C.doCallback(20, 30, cb))
// equivalent types
var goInt8 int8 = 5
var _ C.int8_t = goInt8
// more globals
println("bool:", C.globalBool, C.globalBool2 == true)
println("float:", C.globalFloat)
println("double:", C.globalDouble)
println("complex float:", C.globalComplexFloat)
println("complex double:", C.globalComplexDouble)
println("complex long double:", C.globalComplexLongDouble)
println("char match:", C.globalChar == 100)
var voidPtr unsafe.Pointer = C.globalVoidPtrNull
println("void* match:", voidPtr == nil, C.globalVoidPtrNull == nil, (*C.int)(C.globalVoidPtrSet) == &C.global)
println("int64_t match:", C.globalInt64 == C.int64_t(-(2<<40)))
// 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.unionfield_s())
C.unionSetFloat(3.14)
println("union f:", *C.globalUnion.unionfield_f())
C.unionSetData(5, 8, 1)
data := C.globalUnion.unionfield_data()
println("union global data:", data[0], data[1], data[2])
returnedUnion := printUnion(C.globalUnion)
println("union field:", *returnedUnion.unionfield_f())
var _ C.union_joined = C.globalUnion
printBitfield(&C.globalBitfield)
C.globalBitfield.set_bitfield_a(7)
C.globalBitfield.set_bitfield_b(0)
C.globalBitfield.set_bitfield_c(0xff)
printBitfield(&C.globalBitfield)
// elaborated type
p := C.struct_point2d{x: 3, y: 5}
println("struct:", p.x, p.y)
// multiple anonymous structs (inside a typedef)
var _ C.point2d_t = C.point2d_t{x: 3, y: 5}
var _ C.point3d_t = C.point3d_t{x: 3, y: 5, z: 7}
// nested structs/unions
var _ C.tagged_union_t
var _ C.nested_struct_t
var _ C.nested_union_t
// recursive types, test using a linked list
list := &C.list_t{n: 3, next: &C.struct_list_t{n: 6, next: &C.list_t{n: 7, next: nil}}}
for list != nil {
println("n in chain:", list.n)
list = (*C.list_t)(list.next)
}
// named enum
var _ C.enum_option = C.optionA
var _ C.option_t = C.optionA
println("option:", C.globalOption)
println("option A:", C.optionA)
println("option B:", C.optionB)
println("option C:", C.optionC)
println("option D:", C.optionD)
println("option E:", C.optionE)
println("option F:", C.optionF)
println("option G:", C.optionG)
// anonymous enum
var _ C.option2_t = C.option2A
var _ C.option3_t = C.option3A
println("option 2A:", C.option2A)
println("option 3A:", C.option3A)
// libc: test whether C functions work at all.
buf1 := []byte("foobar\x00")
buf2 := make([]byte, len(buf1))
C.strcpy((*C.char)(unsafe.Pointer(&buf2[0])), (*C.char)(unsafe.Pointer(&buf1[0])))
println("copied string:", string(buf2[:C.strlen((*C.char)(unsafe.Pointer(&buf2[0])))]))
}
func printUnion(union C.joined_t) C.joined_t {
data := union.unionfield_data()
println("union local data: ", data[0], data[1], data[2])
*union.unionfield_s() = -33
println("union s:", data[0] == -33)
*union.unionfield_f() = 6.28
println("union f:", *union.unionfield_f())
return union
}
//export mul
func mul(a, b C.int) C.int {
return a * b
}
func printBitfield(bitfield *C.bitfield_t) {
println("bitfield a:", bitfield.bitfield_a())
println("bitfield b:", bitfield.bitfield_b())
println("bitfield c:", bitfield.bitfield_c())
println("bitfield d:", bitfield.d)
println("bitfield e:", bitfield.e)
}