一、直接写在GO文件中
package main
/*
#include <stdio.h>
void demo(){
printf("HELLO WORLD! \n");
}
*/
import "C"
func main() {
C.demo()
}
构建方式
go build
go build main.go
注: 这种方式只适合代码量特别小的场景
二、写在独立文件中但必须跟main.go文件同一目录
目录结构
.
├── README.md
├── demo.c
├── demo.h
└── main.go
main.go
package main
// #include "demo.h"
import "C"
func main() {
C.demo()
}
demo.h
#ifndef DEMO_H_
#define DEMO_H_
void demo(void);
#endif
demo.c
#include "demo.h"
#include <stdio.h>
void demo(){
printf("HELLO WORLD! \n");
}
构建方式
如果指定go文件,go不会自动构建c文件了
go build
注: 这种方式只适合代码量不算大,几个文件足够的服务
三、静态库
目录结构
.
├── clibs
│ └── demo
│ ├── README.md
│ ├── demo.c
│ ├── demo.h
│ └── main.go
└── main.go
main.go
package main
/*
#cgo CFLAGS: -I./clibs/demo
#cgo LDFLAGS: -L${SRCDIR}/clibs/demo -ldemo
#include "demo.h"
*/
import "C"
func main() {
C.demo()
}
demo.h
#ifndef DEMO_H_
#define DEMO_H_
void demo(void);
#endif
demo.c
#include "demo.h"
#include <stdio.h>
void demo(){
printf("HELLO WORLD! \n");
}
构建方式
cd ./clibs/demo
gcc -c -o demo.o demo.c
ar rcs libdemo.a demo.o
cd ../../
go build
注: 这种方式支持生产环境服务构建,且可以将c文件打包到服务中不会产生额外的运行时依赖,但是静态库一般包含了全部的代码,里面会有大量的符号,如果不同静态库之间出现了符号冲突则会导致链接的失败。
四、动态库
目录结构
.
├── clibs
│ └── demo
│ ├── README.md
│ ├── demo.c
│ ├── demo.h
│ └── main.go
└── main.go
main.go
package main
/*
#cgo CFLAGS: -I./clibs/demo
#cgo LDFLAGS: -L${SRCDIR}/clibs/demo -ldemo
#include "demo.h"
*/
import "C"
func main() {
C.demo()
}
demo.h
#ifndef DEMO_H_
#define DEMO_H_
void demo(void);
#endif
demo.c
#include "demo.h"
#include <stdio.h>
void demo(){
printf("HELLO WORLD! \n");
}
构建方式
cd ./clibs/demo
gcc -shared -o libnumber.so number.c
cd ../../
go build