parent
ab610edb16
commit
fe4f04ba13
|
@ -2,18 +2,24 @@
|
||||||
|
|
||||||
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.
|
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.
|
||||||
|
|
||||||
|
CGO 不但可以使 Go 包访问 C 库,还可以通过 Go 包创建 C 库。
|
||||||
|
|
||||||
## 1.How to
|
## 1.How to
|
||||||
|
|
||||||
### 1.1.Build Go package as C shared library (or shared object)
|
### 1.1.Build Go package as C shared library (or shared object)
|
||||||
|
|
||||||
Every Go **main** package can be built as a C shared library.
|
Every Go **main** package can be built as a C shared library.
|
||||||
|
|
||||||
|
任何 Go **main** 包都可以创建 C 库。
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
go build -go build -buildmode c-shared -o <c-lib>.so <go-package>
|
go build -buildmode=c-shared -o <c-lib>.so
|
||||||
```
|
```
|
||||||
|
|
||||||
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).
|
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).
|
||||||
|
|
||||||
|
以上命令可以创建共享库,该共享库可以被 C、C++、Python、Javascript 等语言访问。
|
||||||
|
|
||||||
Note: Output C shared libraries should be named in standard form **lib\*.so**.
|
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
|
### 1.2.Generate C header and export Go functions as C functions
|
||||||
|
@ -22,11 +28,18 @@ Building a Go **main** package as C shared library doesn’t automatically neith
|
||||||
|
|
||||||
To export a Go function as a C symbol:
|
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 must belong to **main** package.
|
||||||
|
* The Go code file containing the function has to **import "C"**.
|
||||||
|
* Add comment **//export FuncName** on top of the Go function.
|
||||||
* The function signature must not include neither Go struct nor* Go interface nor Go array nor variadic argument.
|
* The function signature must not include neither Go struct nor* Go interface nor Go array nor variadic argument.
|
||||||
|
|
||||||
|
上述命令不会生成 C 头文件并导出符号。若想导出符号并自动生成头文件需要满足以下条件:
|
||||||
|
|
||||||
|
* 要导出的函数必须属于 **main** 包;
|
||||||
|
* Go 源码文件包含 **import "C"**;
|
||||||
|
* 在要导出的函数使用 **//export FuncName** 注释;
|
||||||
|
* 不能使用 Go struct、Go interface、Go arra、以及可变参数。
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
|
|
||||||
|
@ -51,10 +64,14 @@ func cgoSeed(m C.long) {
|
||||||
func cgoRandom(m C.int) C.int {
|
func cgoRandom(m C.int) C.int {
|
||||||
return C.int(rand.Intn(int(m)))
|
return C.int(rand.Intn(int(m)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func main() {}
|
||||||
```
|
```
|
||||||
|
|
||||||
Building above Go **main** package generates a C header file **\<output\>**.h along with a C shared object **\<output\>**.so.
|
Building above Go **main** package generates a C header file **\<output\>**.h along with a C shared object **\<output\>**.so.
|
||||||
|
|
||||||
|
构建以上示例将自动产生头文件和共享库。
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
// Other stuff.
|
// Other stuff.
|
||||||
|
|
||||||
|
@ -69,14 +86,18 @@ Now, every C application can include the generated C header, link to the output
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <cgo-random.h>
|
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
cgoSeed(cgoCurrentMilli());
|
cgoSeed(cgoCurrentMillis());
|
||||||
|
|
||||||
printf("Hello World from C!\n");
|
printf("Hello World from C!\n");
|
||||||
printf("cgoRandom() -> %d\n", cgoRandom(256));
|
printf("cgoRandom() -> %d\n", cgoRandom(256));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
编译方法如下:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
gcc main.c -l<c-lib> -o <exe-file>
|
||||||
|
```
|
||||||
|
|
Loading…
Reference in New Issue