1
0
mirror of https://github.com/chai2010/advanced-go-programming-book.git synced 2025-05-24 04:22:22 +00:00

Merge pull request #30 from lewgun/patch-11

fix typo in ch2.1
This commit is contained in:
chai2010 2018-01-06 12:30:42 +08:00 committed by GitHub
commit d5dc2c1912
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -1,10 +1,10 @@
# 2.1. 你好, CGO!
在第一章的“Hello, World 的革命”一节中我们已经见过一个CGO程序。这一节我们重新给出三个版本的CGO实现简单展示CGO的用法。
在第一章的“Hello, World 的革命”一节中我们已经见过一个CGO程序。这一节我们重新给出三个版本的CGO实现简单展示CGO的用法。
## 基于C标准库
第一章那个CGO程序还不够简单我们现在看看更简单的版本
第一章那个CGO程序还不够简单我们现在看看更简单的版本:
```go
package main
@ -17,15 +17,15 @@ func main() {
}
```
我们通过`import "C"`语句启用CGO特性同时包含C语言的`<stdio.h>`头文件。然后通过CGO包的`C.CString`函数将Go语言字符串转为C语言字符串后调用C语言的`C.puts`函数向标准输出窗口打印转换后的C字符串。
我们通过`import "C"`语句启用CGO特性同时包含C语言的`<stdio.h>`头文件。然后通过CGO包的`C.CString`函数将Go语言字符串转为C语言字符串后调用C语言的`C.puts`函数向标准输出窗口打印转换后的C字符串。
相比“Hello, World 的革命”一节中的CGO程序最大的不同是我们没有在程序退出前释放`C.CString`创建的C语言字符串还有我们改用`puts`函数直接向标准输出打印,之前是采用`fputs`向标准输出打印。
没有释放`C.CString`创建的C语言字符串似乎会导致内存泄露。但是对于这个小程序是没有问题的,因为程序退出后操作系统会自动回收程序的所有资源。
没有释放使用`C.CString`创建的C语言字符串会导致内存泄露。但是对于这个小程序来说,这样是没有问题的,因为程序退出后操作系统会自动回收程序的所有资源。
## 使用自己的C函数
前面我们使用的标准库中已有的函数。我们现在用一个叫`SayHello`的C函数来实现打印然后从Go语言环境中调用这个`SayHello`函数:
前面我们使用了标准库中已有的函数。现在我们先自定义一个叫`SayHello`的C函数来实现打印然后从Go语言环境中调用这个`SayHello`函数:
```go
package main
@ -44,9 +44,9 @@ func main() {
}
```
除了`SayHello`函数是我们自己实现的,其它的部分和前面的例子一本相似。
除了`SayHello`函数是我们自己实现的之外,其它的部分和前面的例子基本相似。
我们也可以将`SayHello`函数放到当前目录下一个C语言源文件中后缀名必须是`.c`)。因为是放到独立的C文件中需要去掉函数的`static`修饰符。
我们也可以将`SayHello`函数放到当前目录下一个C语言源文件中后缀名必须是`.c`)。因为是编写在独立的C文件中为了允许外部引用所以需要去掉函数的`static`修饰符。
```c
// hello.c
@ -71,7 +71,7 @@ func main() {
}
```
既然`SayHello`函数已经放到独立的C文件中了我们自然可以将对应的C文件编译打包为静态库或动态库文件使用。如果是以静态库或动态库方式引用`SayHello`函数的话需要将对应的C源文件移出当前目录CGO构建程序会自动构建当前目录下的C源文件从而导致C函数名冲突。关于静态库等细节在稍后章节讲解。
既然`SayHello`函数已经放到独立的C文件中了我们自然可以将对应的C文件编译打包为静态库或动态库文件使用。如果是以静态库或动态库方式引用`SayHello`函数的话需要将对应的C源文件移出当前目录CGO构建程序会自动构建当前目录下的C源文件从而导致C函数名冲突。关于静态库等细节在稍后章节讲解。
## 用Go来实现C函数
@ -105,7 +105,7 @@ func cgoPuts(s *C.char) {
需要主要的是,这里其实有两个版本的`cgoPuts`函数一个Go语言环境的另一个是C语言环境的。在C语言环境中`SayHello`调用的也是C语言环境的`cgoPuts`函数这是CGO自动生成的桥接函数内部会调用Go语言环境的`cgoPuts`函数。因此我们也可以直接在Go语言环境中调用C语言环境的`cgoPuts`函数。
我们现在可以改用Go语言重新实现C语言接口的`SayHello`函数,然后在`main`函数中还是和之前一样调用`C.SayHello`实现输出:
现在我们可以改用Go语言重新实现C语言接口的`SayHello`函数,然后在`main`函数中还是和之前一样调用`C.SayHello`实现输出:
```go
package main