C語言呼叫GO語言生成的C靜態庫
阿新 • • 發佈:2018-11-28
一開始看別人的例子,自己弄總是不成功,後來也是去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是動態庫
生成靜態庫和標頭檔案
[email protected]:/mnt/d/workspace/src/cktest# go build -o cktest.a -buildmode=c-archive cktest.go [email protected]:/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
[email protected]:/mnt/d/workspace/src/cktest# gcc -o main main.c cktest.a -lpthread
[email protected]:/mnt/d/workspace/src/cktest#
[email protected]:/mnt/d/workspace/src/cktest# ls
cktest.a cktest.go cktest.h main main.c
執行,成功呼叫了GO語言裡的函式。
[email protected]:/mnt/d/workspace/src/cktest# ./main
THis is my testhello hahaha . . .