import "C"

开启 CGO 特性,并且将上方注释中编写的 C 语言语句包装成一个虚拟的 “C” 包。

不同的 Go 包中的 C 包也是不同的,依附于 C 包中类型的方法无法跨包使用。

  • 除非存在对应类型的构造函数

    #cgo 语句

    import "C" 语句前使用,设置编译阶段和链接阶段的相关参数。

环境参数

  • #cgo CFLAGS: [options] 编译阶段参数
    • -D<MACRO=xxx> 定义宏
    • -I<PATH> 头文件包含的检索目录
  • #cgo LDFLAGS: [options] 链接阶段参数
    • -L<PATH> 链接时库文件检索目录
      • 库文件需要绝对目录可以通过 ${SRCDIR} 来表示当前包目录的绝对路径
    • -l<LIB> 链接时需要链接的库
  • 其他编译器环境参数:
    • CPPFLAGS C 和 C++ 共有的编译参数
    • CXXFLAGS C++ 特有的编译选项
    • FFLAGS

条件选择

  1. // Copy from Go 高级编程 P82
  2. package main
  3. /*
  4. #cgo windows CFLAGS: -DX86=1 // Windows 操作系统下指定宏 X86=1
  5. #cgo !windows LDFLAGS: -lm // 非 Windows 操作系统下链接时链接 math 库
  6. // 通过宏区分代码
  7. #cgo windows CFLAGS: -DCGO_OS_WINDOWS=1
  8. #cgo darwin CFLAGS: -DCGO_OS_DARWIN=1
  9. #cgo linux CFLAGS: -DCGO_OS_LINUX=1
  10. #if defined(CGO_OS_WINDOWS)
  11. static const char* os = "windows"
  12. #elif defined(CGO_OS_DARWIN)
  13. static const char* os = "darwin"
  14. #elif defined(CGO_OS_LINUX)
  15. static const char* os = "linux"
  16. #else
  17. # error(unknown os)
  18. #endif
  19. */
  20. import "C"
  21. func main() {
  22. print(C.GoString(C.os))
  23. }

build 标志条件编译

// +build debug
// ...

对于设置了以上 build 标志的源文件,只有在设置 debug 构建标志时才会被构建

$ go build -tags="debug"
$ go build -tags="debug windows" # 多个 tag 用空格分隔

标志组合

// +build windows,amd64 linux
// windows && amd64 || linux