cgo 特性- go调用c语言

176 阅读1分钟

最简单的cgo

// hello.go
package main

import "C"  

func main() {
    println("hello cgo")
}

使用cgo很简单,只需要单独导入一个伪包"C", go代码就可以使用C.*语法引用C语言的部分。 比如类型C.size_t,变量C.stdout,函数C.putchar

preamble

如果import "C"语句之前(放到import语句后就是普通注释),添加一些注释过的C代码,当然这些注释过的叫做preamble.

preamble部分可以包含任何C代码,比如函数声明,变量声明等。

那么基于之前的例子,编写一段最简单的preamble:

// hello.go
package main

//#include <stdio.h>
import "C"

func main() {
    C.puts(C.CString("Hello, World\n"))
}

其中preamble部分加入#include <stdio.h>头,即可以使用stdio的CString函数

当然,通常c语言是以单独模块方式存在的。

hello.c放在同级目录下:

  • hello.c
#include <stdio.h>

void SayHello(const char* s) {
    puts(s);
}
  • main.go
package main
//void SayHello(const char* s);  
import "C"

func main() {
	C.SayHello(C.CString("Hellos, World\n"))
}

通过在main.go的preamble部分添加同级文件hello.c的函数声明,可以调用同级C文件的函数。

调整编译器行为

CFLAGS, CPPFLAGS, CXXFLAGS, FFLAGSLDFLAGS 可以用于调节C,C++,Fortran编译行为。

使用#cgo命令。

package main

// #cgo CFLAGS: -DPNG_DEBUG=1
// #cgo amd64 386 CFLAGS: -DX86=1
// #cgo LDFLAGS: -lpng
// #include <png.h>

//void SayHello(const char* s);
import "C"

func main() {
	C.SayHello(C.CString("Hellos, World\n"))
}

详情参考:cgo

更多go语言高级特性参考: advanced-go-programming