一开始看别人的例子,自己弄总是不成功,后来也是去GO语言社区看多几个例子,找找规律,才把几个自己没注意到的细(keng)节填起来了。
GO语言写一个函数
cktest.go
package main
import (
"C"
"fmt"
)
//export test1
func test1(str string) {
fmt.Println("THis is my test" + str)
}
func main() {
}
这里有几个需要注意的地方
1. 必须有 //export test1 ,对函数的注释,否则不能生成 .h 文件。
Go functions can be executed from C applications. They should be exported by using the following comment line: //export <your_function_name>
2. 必须有import C, 否则不能生成静态库
3. package main, 必须是main, 如果不是, 生成的静态库无法使用,编译链接时会出现cktest.a: error adding symbols: Archive has no index; run ranlib to add one的错误
4. func main() 必须要main函数,否则不能生成静态库
go build -o cktest.a -buildmode=c-archive cktest.go
buildmode中c-archive是静态库,c-shared是动态库
生成静态库和头文件
root@ubuntu:/mnt/d/workspace/src/cktest# go build -o cktest.a -buildmode=c-archive cktest.go
root@ubuntu:/mnt/d/workspace/src/cktest# ls
cktest.a cktest.go cktest.h
// cktest.h
...
typedef struct { const char *p; GoInt n; } GoString;
typedef void *GoMap;
typedef void *GoChan;
typedef struct { void *t; void *v; } GoInterface;
typedef struct { void *data; GoInt len; GoInt cap; } GoSlice;
#endif
/* End of boilerplate cgo prologue. */
#ifdef __cplusplus
extern "C" {
#endif
extern void test1(GoString p0);
#ifdef __cplusplus
}
#endif
C语言写一个主函数
main.c
#include <stdio.h>
#include <string.h>
#include "cktest.h"
int main ()
{
GoString str;
char a[] = "hello hahaha . . . ";
str.p = a;
str.n = strlen(a);
test1(str);
return 0;
}
这里要include头文件,test1()函数声明在头文件里看,str参数就会变成GoString.
编译链接静态库,生成可执行文件
gcc -o main main.c cktest.a -lpthread
root@ubuntu:/mnt/d/workspace/src/cktest# gcc -o main main.c cktest.a -lpthread
root@ubuntu:/mnt/d/workspace/src/cktest#
root@ubuntu:/mnt/d/workspace/src/cktest# ls
cktest.a cktest.go cktest.h main main.c
执行,成功调用了GO语言里的函数。
root@ubuntu:/mnt/d/workspace/src/cktest# ./main
THis is my testhello hahaha . . .