Go
Let's build a Go application using the TEN framework.
Creating the TEN App
First, we'll create a basic TEN Go app by integrating several pre-built TEN packages. Follow these steps:
Installing a Default TEN Extension
Next, install a default TEN extension written in Go:
Declaring the Prebuilt Graph for Auto-Start
Now, we'll modify the property.json
file of the TEN app to include a graph declaration. This will ensure the default extension starts automatically when the TEN app is launched.
Building the App
Unlike standard Go projects, the TEN Go app uses CGo, so you need to set up certain environment variables before building. A build script is already provided in the TEN runtime Go binding system package, so you can build the app with a single command:
The compiled binary, main
, will be generated in the /bin
folder.
Starting the App
Since some environment variables need to be set, it is recommended to start the app using the provided script:
Debugging
If you are using Visual Studio Code (VSCode) as your development environment, you can use the following configurations to debug Go/C code.
Debugging Go Code
Debugging C Code
CGO
Generated Code
When interfacing Go with C, the cgo tool is crucial. When a C function is called from Go, cgo converts the Go source files into multiple output files, including both Go and C source files. These generated C source files are then compiled using compilers like gcc or clang.
Use the following command to generate these C/Go source files:
Example:
The generated files include:
_cgo_export.h is key to the interoperability between Go and C within the cgo context. It contains necessary declarations for Go functions accessible from C.
This file is automatically generated based on Go functions explicitly exported using the
//export
directive. It also includes definitions for C types corresponding to the Go types used in these functions, ensuring compatibility between the two languages.Example of type definitions:
_cgo_gotypes.go contains the corresponding Go types defined in C and used in Go.
For example, if you define a struct
ten_go_error_t
in a header filecommon.h
and useC.ten_go_error_t
in Go, there will be a corresponding Go type in_cgo_gotypes.go
:
cmd.cgo1.go is a cgo-generated counterpart to the original Go source file
cmd.go
. It replaces direct calls to C functions and types with calls to the generated Go functions and types provided by cgo.Example:
cmd.cgo2.c is a wrapper of the original C function called from Go.
Example:
So, the calling sequence of C.ten_go_cmd_create_cmd()
from Go is:
Incomplete Type
As mentioned earlier, the cgo tool generates corresponding Go types in _cgo_gotypes.go
based on C header files imported via import "C"
. If a struct is opaque in the C header, the cgo tool generates an incomplete type instead.
Example of an opaque C struct:
The cgo tool will generate an incomplete type in Go:
What happens if you use the incomplete type in Go?
Incomplete types cannot be allocated.
Since
sys.NotInHeap
cannot be allocated on the Go heap, operations likenew
ormake
won't work. Attempting to create a new instance of an opaque struct in Go will result in a compiler error:
Pointers to incomplete types cannot be passed to C directly.
If you have a C function with a pointer to an opaque struct as a parameter, passing a Go pointer to this incomplete type directly to a C function will not work according to cgo rules. The Go compiler will require the pointer to be "pinned" to ensure it adheres to Go's garbage collector (GC) constraints.
Rules for Using C.uintptr_t Instead of a Pointer to an Opaque Struct
Benefits:
C.uintptr_t
anduintptr
in Go are integers large enough to hold a C pointer, avoiding memory allocation or conversion when passing from Go to C.
Limitations:
uintptr
is an integer, not a pointer. It represents the bit pattern of an address with no pointer arithmetic.uintptr
cannot be dereferenced in Go. Converting it tounsafe.Pointer
can cause issues with Go's GC.Since
uintptr
is an integer,nil
orNULL
cannot be passed to C. Use0
instead ofnil
to represent a null address.
Last updated