diff --git a/Software/Development/Language/Go/Basic/Build_and_Use_Go_Packages_as_C_Libraries.md b/Software/Development/Language/Go/Basic/Build_and_Use_Go_Packages_as_C_Libraries.md index a2ba9ea..0a8a9df 100644 --- a/Software/Development/Language/Go/Basic/Build_and_Use_Go_Packages_as_C_Libraries.md +++ b/Software/Development/Language/Go/Basic/Build_and_Use_Go_Packages_as_C_Libraries.md @@ -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 不但可以使 Go 包访问 C 库,还可以通过 Go 包创建 C 库。 + ## 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. +任何 Go **main** 包都可以创建 C 库。 + ```bash -go build -go build -buildmode c-shared -o .so +go build -buildmode=c-shared -o .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). +以上命令可以创建共享库,该共享库可以被 C、C++、Python、Javascript 等语言访问。 + 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 @@ -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: -* 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 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. +上述命令不会生成 C 头文件并导出符号。若想导出符号并自动生成头文件需要满足以下条件: + +* 要导出的函数必须属于 **main** 包; +* Go 源码文件包含 **import "C"**; +* 在要导出的函数使用 **//export FuncName** 注释; +* 不能使用 Go struct、Go interface、Go arra、以及可变参数。 + ```go package main @@ -51,10 +64,14 @@ func cgoSeed(m C.long) { func cgoRandom(m C.int) C.int { return C.int(rand.Intn(int(m))) } + +func main() {} ``` Building above Go **main** package generates a C header file **\**.h along with a C shared object **\**.so. +构建以上示例将自动产生头文件和共享库。 + ```cpp // Other stuff. @@ -69,14 +86,18 @@ Now, every C application can include the generated C header, link to the output ```cpp #include -#include int main() { - cgoSeed(cgoCurrentMilli()); - + cgoSeed(cgoCurrentMillis()); + printf("Hello World from C!\n"); printf("cgoRandom() -> %d\n", cgoRandom(256)); - return 0; } ``` + +编译方法如下: + +```bash +gcc main.c -l -o +```