go语言静态链接 golang 静态文件服务器( 二 )


更多 cgo 的资源
cgo的文档中包含了关于C伪包的更多详细的说明, 以及构建过程. Go代码树中的cgo的例子给出了更多更高级的用法.
一个简单而又符合Go惯用法的基于cgo的包是Russ Cox写的gosqlite. 而Go语言的网站上也列出了更多的的cgo包.
最后, 如果你对于cgo的内部是怎么运作这个事情感到好奇的话, 去看看运行时包的cgocall.c文件的注释吧.
linux环境中golang使用glibc吗?默认是动态链接go语言静态链接了glibcgo语言静态链接,但go语言静态链接你也可以通过编译选项改成静态链接或者使用纯go库 。
go语言如何调用c函数直接嵌入c源代码到go代码里面
package main
/*
#include stdio.h
void myhello(int i) {
printf("Hello C: %d\n", i);
}
*/
import "C"
import "fmt"
func main() {
C.myhello(C.int(12))
fmt.Println("Hello Go");
}
需要注意的是C代码必须放在注释里面
import "C"语句和前面的C代码之间不能有空行
运行结果
$ go build main.go./main
Hello C: 12
Hello Go
分开c代码到单独文件
嵌在一起代码结构不是很好看,很多人包括我,还是喜欢把两个分开,放在不同的文件里面,显得干净 , go源文件里面是go的源代码,c源文件里面是c的源代码 。
$ ls
hello.chello.hmain.go
$ cat hello.h
void hello(int);
$ cat hello.c
#include stdio.h
void hello(int i) {
printf("Hello C: %d\n", i);
}
$ cat main.go
package main
// #include "hello.h"
import "C"
import "fmt"
func main() {
C.hello(C.int(12))
fmt.Println("Hello Go");
}
编译运行
$ go build./main
Hello C: 12
Hello Go
编译成库文件
如果c文件比较多,最好还是能够编译成一个独立的库文件 , 然后go来调用库 。
$ find mylib main
mylib
mylib/hello.h
mylib/hello.c
main
main/main.go
编译库文件
$ cd mylib
# gcc -fPIC -shared -o libhello.so hello.c
编译go程序
$ cd main
$ cat main.go
package main
// #cgo CFLAGS: -I../mylib
// #cgo LDFLAGS: -L../mylib -lhello
// #include "hello.h"
import "C"
import "fmt"
func main() {
C.hello(C.int(12))
fmt.Println("Hello Go");
}
$ go build main.go
运行
$ export LD_LIBRARY_PATH=../mylib
$ ./main
Hello C: 12
Hello Go
在我们的例子中,库文件是编译成动态库的,main程序链接的时候也是采用的动态库
$ ldd main
linux-vdso.so.1 =(0x00007fffc7968000)
libhello.so = ../mylib/libhello.so (0x00007f513684c000)
libpthread.so.0 = /lib64/libpthread.so.0 (0x00007f5136614000)
libc.so.6 = /lib64/libc.so.6 (0x00007f5136253000)
/lib64/ld-linux-x86-64.so.2 (0x000055d819227000)
理论上讲也是可以编译成整个一静态链接的可执行程序 , 由于我的机器上缺少静态链接的系统库,比如libc.a,所以只能编译成动态链接 。
Go语言的特点 类型 在变量名后边
也可不显式声明类型, 类型推断,但是是静态语言, name一开始放字符串就不能再赋值数字
方法,属性 分开方法名首字母大写就是就是外部可调的
面向对象设计的一个重要原则:“优先使用组合而不是继承”
Dog 也是Animal , 要复用Animal的属性和方法,
只需要在结构体 type里面写 Animal
入口也是main, 用用试试
多态, 有这个方法就是这个接口的实现,具体的类 不需要知道自己实现了什么接口,
使用: 在一个函数调用之前加上关键字go 就启动了一个goroutine
创建一个goroutine,它会被加入到一个全局的运行队列当中,