Build and Use Go Packages as C Libraries
Signed-off-by: rick.chan <chenyang@autoai.com>
This commit is contained in:
parent
77705f7a57
commit
ab610edb16
|
@ -0,0 +1,82 @@
|
|||
# Build and Use Go Packages as C Libraries
|
||||
|
||||
CGO is an official builtin feature of Go, it enables the creation of Go packages that reference to C libraries. But it isn’t just that, it is achievable in the opposite direction, too. It enables creation of C libraries from Go packages so that C code can reference to Go, which is mind-blowing.
|
||||
|
||||
## 1.How to
|
||||
|
||||
### 1.1.Build Go package as C shared library (or shared object)
|
||||
|
||||
Every Go **main** package can be built as a C shared library.
|
||||
|
||||
```bash
|
||||
go build -go build -buildmode c-shared -o <c-lib>.so <go-package>
|
||||
```
|
||||
|
||||
Executing above command builds target Go **main** package and all of its dependencies as a single C shared library, which can be distributed, installed and linked to every C application and applications in other programming languages that can reference C shared libraries (C++, Python, Javascript, etc).
|
||||
|
||||
Note: Output C shared libraries should be named in standard form **lib\*.so**.
|
||||
|
||||
### 1.2.Generate C header and export Go functions as C functions
|
||||
|
||||
Building a Go **main** package as C shared library doesn’t automatically neither generate C header nor expose any Go function as C symbol. Developers have to explicitly indicate which Go functions to be exposed.
|
||||
|
||||
To export a Go function as a C symbol:
|
||||
|
||||
* Add comment **//export FuncName** on top of the Go function.
|
||||
* The Go code file containing the function has to **import "C"**.
|
||||
* The function must belong to **main** package.
|
||||
* The function signature must not include neither Go struct nor* Go interface nor Go array nor variadic argument.
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
"time"
|
||||
)
|
||||
|
||||
//export cgoCurrentMillis
|
||||
func cgoCurrentMillis() C.long {
|
||||
return C.long(time.Now().Unix())
|
||||
}
|
||||
|
||||
//export cgoSeed
|
||||
func cgoSeed(m C.long) {
|
||||
rand.Seed(int64(m))
|
||||
}
|
||||
|
||||
//export cgoRandom
|
||||
func cgoRandom(m C.int) C.int {
|
||||
return C.int(rand.Intn(int(m)))
|
||||
}
|
||||
```
|
||||
|
||||
Building above Go **main** package generates a C header file **\<output\>**.h along with a C shared object **\<output\>**.so.
|
||||
|
||||
```cpp
|
||||
// Other stuff.
|
||||
|
||||
extern long int cgoCurrentMillis();
|
||||
extern void cgoSeed(long int p0);
|
||||
extern int cgoRandom(int p0);
|
||||
```
|
||||
|
||||
**cgoCurrentMilli**, **cgoSeed** and **cgoRandom** are exposed as C symbols in **\<output\>**.so, too.
|
||||
|
||||
Now, every C application can include the generated C header, link to the output C shared library and use exposed C symbols.
|
||||
|
||||
```cpp
|
||||
#include <stdio.h>
|
||||
#include <cgo-random.h>
|
||||
|
||||
int main() {
|
||||
cgoSeed(cgoCurrentMilli());
|
||||
|
||||
printf("Hello World from C!\n");
|
||||
printf("cgoRandom() -> %d\n", cgoRandom(256));
|
||||
|
||||
return 0;
|
||||
}
|
||||
```
|
Loading…
Reference in New Issue